|  | /* | 
|  | * 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 <openssl/idea.h> | 
|  | #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); | 
|  | } |