/* * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include #include "idea_lcl.h" static IDEA_INT inverse(unsigned int xin); void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) { int i; register IDEA_INT *kt, *kf, r0, r1, r2; kt = &(ks->data[0][0]); n2s(key, kt[0]); n2s(key, kt[1]); n2s(key, kt[2]); n2s(key, kt[3]); n2s(key, kt[4]); n2s(key, kt[5]); n2s(key, kt[6]); n2s(key, kt[7]); kf = kt; kt += 8; for (i = 0; i < 6; i++) { r2 = kf[1]; r1 = kf[2]; *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; r0 = kf[3]; *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; r1 = kf[4]; *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; r0 = kf[5]; *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; r1 = kf[6]; *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; r0 = kf[7]; *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; r1 = kf[0]; if (i >= 5) break; *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; kf += 8; } } void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) { int r; register IDEA_INT *fp, *tp, t; tp = &(dk->data[0][0]); fp = &(ek->data[8][0]); for (r = 0; r < 9; r++) { *(tp++) = inverse(fp[0]); *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); *(tp++) = inverse(fp[3]); if (r == 8) break; fp -= 6; *(tp++) = fp[4]; *(tp++) = fp[5]; } tp = &(dk->data[0][0]); t = tp[1]; tp[1] = tp[2]; tp[2] = t; t = tp[49]; tp[49] = tp[50]; tp[50] = t; } /* taken directly from the 'paper' I'll have a look at it later */ static IDEA_INT inverse(unsigned int xin) { long n1, n2, q, r, b1, b2, t; if (xin == 0) b2 = 0; else { n1 = 0x10001; n2 = xin; b2 = 1; b1 = 0; do { r = (n1 % n2); q = (n1 - r) / n2; if (r == 0) { if (b2 < 0) b2 = 0x10001 + b2; } else { n1 = n2; n2 = r; t = b2; b2 = b1 - q * b2; b1 = t; } } while (r != 0); } return ((IDEA_INT) b2); }