1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.]. */ 56 57 #include <openssl/cast.h> 58 #include <openssl/cipher.h> 59 #include <openssl/obj.h> 60 61 #if defined(OPENSSL_WINDOWS) 62 OPENSSL_MSVC_PRAGMA(warning(push, 3)) 63 #include <intrin.h> 64 OPENSSL_MSVC_PRAGMA(warning(pop)) 65 #endif 66 67 #include "../../crypto/internal.h" 68 #include "internal.h" 69 #include "../macros.h" 70 71 72 void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks, 73 int enc) { 74 uint32_t d[2]; 75 76 n2l(in, d[0]); 77 n2l(in, d[1]); 78 if (enc) { 79 CAST_encrypt(d, ks); 80 } else { 81 CAST_decrypt(d, ks); 82 } 83 l2n(d[0], out); 84 l2n(d[1], out); 85 } 86 87 #if defined(OPENSSL_WINDOWS) && defined(_MSC_VER) 88 #define ROTL(a, n) (_lrotl(a, n)) 89 #else 90 #define ROTL(a, n) ((((a) << (n)) | ((a) >> ((-(n))&31))) & 0xffffffffL) 91 #endif 92 93 #define E_CAST(n, key, L, R, OP1, OP2, OP3) \ 94 { \ 95 uint32_t a, b, c, d; \ 96 t = (key[n * 2] OP1 R) & 0xffffffff; \ 97 t = ROTL(t, (key[n * 2 + 1])); \ 98 a = CAST_S_table0[(t >> 8) & 0xff]; \ 99 b = CAST_S_table1[(t)&0xff]; \ 100 c = CAST_S_table2[(t >> 24) & 0xff]; \ 101 d = CAST_S_table3[(t >> 16) & 0xff]; \ 102 L ^= (((((a OP2 b)&0xffffffffL)OP3 c) & 0xffffffffL)OP1 d) & 0xffffffffL; \ 103 } 104 105 void CAST_encrypt(uint32_t *data, const CAST_KEY *key) { 106 uint32_t l, r, t; 107 const uint32_t *k; 108 109 k = &key->data[0]; 110 l = data[0]; 111 r = data[1]; 112 113 E_CAST(0, k, l, r, +, ^, -); 114 E_CAST(1, k, r, l, ^, -, +); 115 E_CAST(2, k, l, r, -, +, ^); 116 E_CAST(3, k, r, l, +, ^, -); 117 E_CAST(4, k, l, r, ^, -, +); 118 E_CAST(5, k, r, l, -, +, ^); 119 E_CAST(6, k, l, r, +, ^, -); 120 E_CAST(7, k, r, l, ^, -, +); 121 E_CAST(8, k, l, r, -, +, ^); 122 E_CAST(9, k, r, l, +, ^, -); 123 E_CAST(10, k, l, r, ^, -, +); 124 E_CAST(11, k, r, l, -, +, ^); 125 126 if (!key->short_key) { 127 E_CAST(12, k, l, r, +, ^, -); 128 E_CAST(13, k, r, l, ^, -, +); 129 E_CAST(14, k, l, r, -, +, ^); 130 E_CAST(15, k, r, l, +, ^, -); 131 } 132 133 data[1] = l & 0xffffffffL; 134 data[0] = r & 0xffffffffL; 135 } 136 137 void CAST_decrypt(uint32_t *data, const CAST_KEY *key) { 138 uint32_t l, r, t; 139 const uint32_t *k; 140 141 k = &key->data[0]; 142 l = data[0]; 143 r = data[1]; 144 145 if (!key->short_key) { 146 E_CAST(15, k, l, r, +, ^, -); 147 E_CAST(14, k, r, l, -, +, ^); 148 E_CAST(13, k, l, r, ^, -, +); 149 E_CAST(12, k, r, l, +, ^, -); 150 } 151 152 E_CAST(11, k, l, r, -, +, ^); 153 E_CAST(10, k, r, l, ^, -, +); 154 E_CAST(9, k, l, r, +, ^, -); 155 E_CAST(8, k, r, l, -, +, ^); 156 E_CAST(7, k, l, r, ^, -, +); 157 E_CAST(6, k, r, l, +, ^, -); 158 E_CAST(5, k, l, r, -, +, ^); 159 E_CAST(4, k, r, l, ^, -, +); 160 E_CAST(3, k, l, r, +, ^, -); 161 E_CAST(2, k, r, l, -, +, ^); 162 E_CAST(1, k, l, r, ^, -, +); 163 E_CAST(0, k, r, l, +, ^, -); 164 165 data[1] = l & 0xffffffffL; 166 data[0] = r & 0xffffffffL; 167 } 168 169 void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, 170 const CAST_KEY *ks, uint8_t *iv, int enc) { 171 uint32_t tin0, tin1; 172 uint32_t tout0, tout1, xor0, xor1; 173 size_t l = length; 174 uint32_t tin[2]; 175 176 if (enc) { 177 n2l(iv, tout0); 178 n2l(iv, tout1); 179 iv -= 8; 180 while (l >= 8) { 181 n2l(in, tin0); 182 n2l(in, tin1); 183 tin0 ^= tout0; 184 tin1 ^= tout1; 185 tin[0] = tin0; 186 tin[1] = tin1; 187 CAST_encrypt(tin, ks); 188 tout0 = tin[0]; 189 tout1 = tin[1]; 190 l2n(tout0, out); 191 l2n(tout1, out); 192 l -= 8; 193 } 194 if (l != 0) { 195 n2ln(in, tin0, tin1, l); 196 tin0 ^= tout0; 197 tin1 ^= tout1; 198 tin[0] = tin0; 199 tin[1] = tin1; 200 CAST_encrypt(tin, ks); 201 tout0 = tin[0]; 202 tout1 = tin[1]; 203 l2n(tout0, out); 204 l2n(tout1, out); 205 } 206 l2n(tout0, iv); 207 l2n(tout1, iv); 208 } else { 209 n2l(iv, xor0); 210 n2l(iv, xor1); 211 iv -= 8; 212 while (l >= 8) { 213 n2l(in, tin0); 214 n2l(in, tin1); 215 tin[0] = tin0; 216 tin[1] = tin1; 217 CAST_decrypt(tin, ks); 218 tout0 = tin[0] ^ xor0; 219 tout1 = tin[1] ^ xor1; 220 l2n(tout0, out); 221 l2n(tout1, out); 222 xor0 = tin0; 223 xor1 = tin1; 224 l -= 8; 225 } 226 if (l != 0) { 227 n2l(in, tin0); 228 n2l(in, tin1); 229 tin[0] = tin0; 230 tin[1] = tin1; 231 CAST_decrypt(tin, ks); 232 tout0 = tin[0] ^ xor0; 233 tout1 = tin[1] ^ xor1; 234 l2nn(tout0, tout1, out, l); 235 xor0 = tin0; 236 xor1 = tin1; 237 } 238 l2n(xor0, iv); 239 l2n(xor1, iv); 240 } 241 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 242 tin[0] = tin[1] = 0; 243 } 244 245 #define CAST_exp(l, A, a, n) \ 246 A[n / 4] = l; \ 247 a[n + 3] = (l)&0xff; \ 248 a[n + 2] = (l >> 8) & 0xff; \ 249 a[n + 1] = (l >> 16) & 0xff; \ 250 a[n + 0] = (l >> 24) & 0xff; 251 #define S4 CAST_S_table4 252 #define S5 CAST_S_table5 253 #define S6 CAST_S_table6 254 #define S7 CAST_S_table7 255 256 void CAST_set_key(CAST_KEY *key, size_t len, const uint8_t *data) { 257 uint32_t x[16]; 258 uint32_t z[16]; 259 uint32_t k[32]; 260 uint32_t X[4], Z[4]; 261 uint32_t l, *K; 262 size_t i; 263 264 for (i = 0; i < 16; i++) { 265 x[i] = 0; 266 } 267 268 if (len > 16) { 269 len = 16; 270 } 271 272 for (i = 0; i < len; i++) { 273 x[i] = data[i]; 274 } 275 276 if (len <= 10) { 277 key->short_key = 1; 278 } else { 279 key->short_key = 0; 280 } 281 282 K = &k[0]; 283 X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL; 284 X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL; 285 X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL; 286 X[3] = ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL; 287 288 for (;;) { 289 l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; 290 CAST_exp(l, Z, z, 0); 291 l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; 292 CAST_exp(l, Z, z, 4); 293 l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; 294 CAST_exp(l, Z, z, 8); 295 l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; 296 CAST_exp(l, Z, z, 12); 297 298 K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]]; 299 K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]]; 300 K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]]; 301 K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]]; 302 303 l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; 304 CAST_exp(l, X, x, 0); 305 l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; 306 CAST_exp(l, X, x, 4); 307 l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; 308 CAST_exp(l, X, x, 8); 309 l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; 310 CAST_exp(l, X, x, 12); 311 312 K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]]; 313 K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]]; 314 K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]]; 315 K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]]; 316 317 l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; 318 CAST_exp(l, Z, z, 0); 319 l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; 320 CAST_exp(l, Z, z, 4); 321 l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; 322 CAST_exp(l, Z, z, 8); 323 l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; 324 CAST_exp(l, Z, z, 12); 325 326 K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]]; 327 K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]]; 328 K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]]; 329 K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]]; 330 331 l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; 332 CAST_exp(l, X, x, 0); 333 l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; 334 CAST_exp(l, X, x, 4); 335 l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; 336 CAST_exp(l, X, x, 8); 337 l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; 338 CAST_exp(l, X, x, 12); 339 340 K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]]; 341 K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]]; 342 K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]]; 343 K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]]; 344 if (K != k) { 345 break; 346 } 347 K += 16; 348 } 349 350 for (i = 0; i < 16; i++) { 351 key->data[i * 2] = k[i]; 352 key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f; 353 } 354 } 355 356 // The input and output encrypted as though 64bit cfb mode is being used. The 357 // extra state information to record how much of the 64bit block we have used 358 // is contained in *num. 359 void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, size_t length, 360 const CAST_KEY *schedule, uint8_t *ivec, int *num, 361 int enc) { 362 uint32_t v0, v1, t; 363 int n = *num; 364 size_t l = length; 365 uint32_t ti[2]; 366 uint8_t *iv, c, cc; 367 368 iv = ivec; 369 if (enc) { 370 while (l--) { 371 if (n == 0) { 372 n2l(iv, v0); 373 ti[0] = v0; 374 n2l(iv, v1); 375 ti[1] = v1; 376 CAST_encrypt((uint32_t *)ti, schedule); 377 iv = ivec; 378 t = ti[0]; 379 l2n(t, iv); 380 t = ti[1]; 381 l2n(t, iv); 382 iv = ivec; 383 } 384 c = *(in++) ^ iv[n]; 385 *(out++) = c; 386 iv[n] = c; 387 n = (n + 1) & 0x07; 388 } 389 } else { 390 while (l--) { 391 if (n == 0) { 392 n2l(iv, v0); 393 ti[0] = v0; 394 n2l(iv, v1); 395 ti[1] = v1; 396 CAST_encrypt((uint32_t *)ti, schedule); 397 iv = ivec; 398 t = ti[0]; 399 l2n(t, iv); 400 t = ti[1]; 401 l2n(t, iv); 402 iv = ivec; 403 } 404 cc = *(in++); 405 c = iv[n]; 406 iv[n] = cc; 407 *(out++) = c ^ cc; 408 n = (n + 1) & 0x07; 409 } 410 } 411 v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; 412 *num = n; 413 } 414 415 static int cast_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, 416 const uint8_t *iv, int enc) { 417 CAST_KEY *cast_key = ctx->cipher_data; 418 CAST_set_key(cast_key, ctx->key_len, key); 419 return 1; 420 } 421 422 static int cast_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, 423 size_t len) { 424 CAST_KEY *cast_key = ctx->cipher_data; 425 426 while (len >= CAST_BLOCK) { 427 CAST_ecb_encrypt(in, out, cast_key, ctx->encrypt); 428 in += CAST_BLOCK; 429 out += CAST_BLOCK; 430 len -= CAST_BLOCK; 431 } 432 assert(len == 0); 433 434 return 1; 435 } 436 437 static int cast_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, 438 size_t len) { 439 CAST_KEY *cast_key = ctx->cipher_data; 440 CAST_cbc_encrypt(in, out, len, cast_key, ctx->iv, ctx->encrypt); 441 return 1; 442 } 443 444 static const EVP_CIPHER cast5_ecb = { 445 NID_cast5_ecb, CAST_BLOCK, 446 CAST_KEY_LENGTH, CAST_BLOCK /* iv_len */, 447 sizeof(CAST_KEY), EVP_CIPH_ECB_MODE | EVP_CIPH_VARIABLE_LENGTH, 448 NULL /* app_data */, cast_init_key, 449 cast_ecb_cipher, NULL /* cleanup */, 450 NULL /* ctrl */, 451 }; 452 453 static const EVP_CIPHER cast5_cbc = { 454 NID_cast5_cbc, CAST_BLOCK, 455 CAST_KEY_LENGTH, CAST_BLOCK /* iv_len */, 456 sizeof(CAST_KEY), EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH, 457 NULL /* app_data */, cast_init_key, 458 cast_cbc_cipher, NULL /* cleanup */, 459 NULL /* ctrl */, 460 }; 461 462 const EVP_CIPHER *EVP_cast5_ecb(void) { return &cast5_ecb; } 463 464 const EVP_CIPHER *EVP_cast5_cbc(void) { return &cast5_cbc; } 465