1/* $OpenBSD: idea.c,v 1.1 2024/03/29 05:23:50 jsing Exp $ */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <openssl/idea.h> 60#include "idea_local.h" 61 62void 63idea_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 64 IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int encrypt) 65{ 66 unsigned long tin0, tin1; 67 unsigned long tout0, tout1, xor0, xor1; 68 long l = length; 69 unsigned long tin[2]; 70 71 if (encrypt) { 72 n2l(iv, tout0); 73 n2l(iv, tout1); 74 iv -= 8; 75 for (l -= 8; l >= 0; l -= 8) 76 { 77 n2l(in, tin0); 78 n2l(in, tin1); 79 tin0 ^= tout0; 80 tin1 ^= tout1; 81 tin[0] = tin0; 82 tin[1] = tin1; 83 idea_encrypt(tin, ks); 84 tout0 = tin[0]; 85 l2n(tout0, out); 86 tout1 = tin[1]; 87 l2n(tout1, out); 88 } 89 if (l != -8) { 90 n2ln(in, tin0, tin1, l + 8); 91 tin0 ^= tout0; 92 tin1 ^= tout1; 93 tin[0] = tin0; 94 tin[1] = tin1; 95 idea_encrypt(tin, ks); 96 tout0 = tin[0]; 97 l2n(tout0, out); 98 tout1 = tin[1]; 99 l2n(tout1, out); 100 } 101 l2n(tout0, iv); 102 l2n(tout1, iv); 103 } else { 104 n2l(iv, xor0); 105 n2l(iv, xor1); 106 iv -= 8; 107 for (l -= 8; l >= 0; l -= 8) 108 { 109 n2l(in, tin0); 110 tin[0] = tin0; 111 n2l(in, tin1); 112 tin[1] = tin1; 113 idea_encrypt(tin, ks); 114 tout0 = tin[0] ^ xor0; 115 tout1 = tin[1] ^ xor1; 116 l2n(tout0, out); 117 l2n(tout1, out); 118 xor0 = tin0; 119 xor1 = tin1; 120 } 121 if (l != -8) { 122 n2l(in, tin0); 123 tin[0] = tin0; 124 n2l(in, tin1); 125 tin[1] = tin1; 126 idea_encrypt(tin, ks); 127 tout0 = tin[0] ^ xor0; 128 tout1 = tin[1] ^ xor1; 129 l2nn(tout0, tout1, out, l + 8); 130 xor0 = tin0; 131 xor1 = tin1; 132 } 133 l2n(xor0, iv); 134 l2n(xor1, iv); 135 } 136 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 137 tin[0] = tin[1] = 0; 138} 139LCRYPTO_ALIAS(idea_cbc_encrypt); 140 141void 142idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key) 143{ 144 IDEA_INT *p; 145 unsigned long x1, x2, x3, x4, t0, t1, ul; 146 147 x2 = d[0]; 148 x1 = (x2 >> 16); 149 x4 = d[1]; 150 x3 = (x4 >> 16); 151 152 p = &(key->data[0][0]); 153 154 E_IDEA(0); 155 E_IDEA(1); 156 E_IDEA(2); 157 E_IDEA(3); 158 E_IDEA(4); 159 E_IDEA(5); 160 E_IDEA(6); 161 E_IDEA(7); 162 163 x1 &= 0xffff; 164 idea_mul(x1, x1, *p, ul); 165 p++; 166 167 t0 = x3 + *(p++); 168 t1 = x2 + *(p++); 169 170 x4 &= 0xffff; 171 idea_mul(x4, x4, *p, ul); 172 173 d[0] = (t0 & 0xffff)|((x1 & 0xffff) << 16); 174 d[1] = (x4 & 0xffff)|((t1 & 0xffff) << 16); 175} 176LCRYPTO_ALIAS(idea_encrypt); 177 178/* The input and output encrypted as though 64bit cfb mode is being 179 * used. The extra state information to record how much of the 180 * 64bit block we have used is contained in *num; 181 */ 182 183void 184idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, 185 long length, IDEA_KEY_SCHEDULE *schedule, 186 unsigned char *ivec, int *num, int encrypt) 187{ 188 unsigned long v0, v1, t; 189 int n = *num; 190 long l = length; 191 unsigned long ti[2]; 192 unsigned char *iv, c, cc; 193 194 iv = (unsigned char *)ivec; 195 if (encrypt) { 196 while (l--) { 197 if (n == 0) { 198 n2l(iv, v0); 199 ti[0] = v0; 200 n2l(iv, v1); 201 ti[1] = v1; 202 idea_encrypt((unsigned long *)ti, schedule); 203 iv = (unsigned char *)ivec; 204 t = ti[0]; 205 l2n(t, iv); 206 t = ti[1]; 207 l2n(t, iv); 208 iv = (unsigned char *)ivec; 209 } 210 c = *(in++) ^ iv[n]; 211 *(out++) = c; 212 iv[n] = c; 213 n = (n + 1) & 0x07; 214 } 215 } else { 216 while (l--) { 217 if (n == 0) { 218 n2l(iv, v0); 219 ti[0] = v0; 220 n2l(iv, v1); 221 ti[1] = v1; 222 idea_encrypt((unsigned long *)ti, schedule); 223 iv = (unsigned char *)ivec; 224 t = ti[0]; 225 l2n(t, iv); 226 t = ti[1]; 227 l2n(t, iv); 228 iv = (unsigned char *)ivec; 229 } 230 cc = *(in++); 231 c = iv[n]; 232 iv[n] = cc; 233 *(out++) = c ^ cc; 234 n = (n + 1) & 0x07; 235 } 236 } 237 v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; 238 *num = n; 239} 240LCRYPTO_ALIAS(idea_cfb64_encrypt); 241 242void 243idea_ecb_encrypt(const unsigned char *in, unsigned char *out, 244 IDEA_KEY_SCHEDULE *ks) 245{ 246 unsigned long l0, l1, d[2]; 247 248 n2l(in, l0); 249 d[0] = l0; 250 n2l(in, l1); 251 d[1] = l1; 252 idea_encrypt(d, ks); 253 l0 = d[0]; 254 l2n(l0, out); 255 l1 = d[1]; 256 l2n(l1, out); 257 l0 = l1 = d[0] = d[1] = 0; 258} 259LCRYPTO_ALIAS(idea_ecb_encrypt); 260 261/* 262 * The input and output encrypted as though 64bit ofb mode is being 263 * used. The extra state information to record how much of the 264 * 64bit block we have used is contained in *num; 265 */ 266void 267idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, 268 long length, IDEA_KEY_SCHEDULE *schedule, 269 unsigned char *ivec, int *num) 270{ 271 unsigned long v0, v1, t; 272 int n = *num; 273 long l = length; 274 unsigned char d[8]; 275 char *dp; 276 unsigned long ti[2]; 277 unsigned char *iv; 278 int save = 0; 279 280 iv = (unsigned char *)ivec; 281 n2l(iv, v0); 282 n2l(iv, v1); 283 ti[0] = v0; 284 ti[1] = v1; 285 dp = (char *)d; 286 l2n(v0, dp); 287 l2n(v1, dp); 288 while (l--) { 289 if (n == 0) { 290 idea_encrypt((unsigned long *)ti, schedule); 291 dp = (char *)d; 292 t = ti[0]; 293 l2n(t, dp); 294 t = ti[1]; 295 l2n(t, dp); 296 save++; 297 } 298 *(out++) = *(in++) ^ d[n]; 299 n = (n + 1) & 0x07; 300 } 301 if (save) { 302 v0 = ti[0]; 303 v1 = ti[1]; 304 iv = (unsigned char *)ivec; 305 l2n(v0, iv); 306 l2n(v1, iv); 307 } 308 t = v0 = v1 = ti[0] = ti[1] = 0; 309 *num = n; 310} 311LCRYPTO_ALIAS(idea_ofb64_encrypt); 312 313/* taken directly from the 'paper' I'll have a look at it later */ 314static IDEA_INT 315inverse(unsigned int xin) 316{ 317 long n1, n2, q, r, b1, b2, t; 318 319 if (xin == 0) 320 b2 = 0; 321 else { 322 n1 = 0x10001; 323 n2 = xin; 324 b2 = 1; 325 b1 = 0; 326 327 do { 328 r = (n1 % n2); 329 q = (n1 - r)/n2; 330 if (r == 0) { 331 if (b2 < 0) 332 b2 = 0x10001 + b2; 333 } else { 334 n1 = n2; 335 n2 = r; 336 t = b2; 337 b2 = b1 - q*b2; 338 b1 = t; 339 } 340 } while (r != 0); 341 } 342 return ((IDEA_INT)b2); 343} 344 345void 346idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) 347{ 348 int i; 349 IDEA_INT *kt, *kf, r0, r1, r2; 350 351 kt = &(ks->data[0][0]); 352 n2s(key, kt[0]); 353 n2s(key, kt[1]); 354 n2s(key, kt[2]); 355 n2s(key, kt[3]); 356 n2s(key, kt[4]); 357 n2s(key, kt[5]); 358 n2s(key, kt[6]); 359 n2s(key, kt[7]); 360 361 kf = kt; 362 kt += 8; 363 for (i = 0; i < 6; i++) 364 { 365 r2 = kf[1]; 366 r1 = kf[2]; 367 *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; 368 r0 = kf[3]; 369 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 370 r1 = kf[4]; 371 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 372 r0 = kf[5]; 373 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 374 r1 = kf[6]; 375 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 376 r0 = kf[7]; 377 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 378 r1 = kf[0]; 379 if (i >= 5) 380 break; 381 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 382 *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; 383 kf += 8; 384 } 385} 386LCRYPTO_ALIAS(idea_set_encrypt_key); 387 388void 389idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) 390{ 391 int r; 392 IDEA_INT *fp, *tp, t; 393 394 tp = &(dk->data[0][0]); 395 fp = &(ek->data[8][0]); 396 for (r = 0; r < 9; r++) 397 { 398 *(tp++) = inverse(fp[0]); 399 *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); 400 *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); 401 *(tp++) = inverse(fp[3]); 402 if (r == 8) 403 break; 404 fp -= 6; 405 *(tp++) = fp[4]; 406 *(tp++) = fp[5]; 407 } 408 409 tp = &(dk->data[0][0]); 410 t = tp[1]; 411 tp[1] = tp[2]; 412 tp[2] = t; 413 414 t = tp[49]; 415 tp[49] = tp[50]; 416 tp[50] = t; 417} 418LCRYPTO_ALIAS(idea_set_decrypt_key); 419