1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/idea.h> 11 #include <inttypes.h> 12 #include "idea_lcl.h" 13 14 static IDEA_INT inverse(unsigned int xin); 15 void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) 16 { 17 int i; 18 register IDEA_INT *kt, *kf, r0, r1, r2; 19 20 kt = &(ks->data[0][0]); 21 n2s(key, kt[0]); 22 n2s(key, kt[1]); 23 n2s(key, kt[2]); 24 n2s(key, kt[3]); 25 n2s(key, kt[4]); 26 n2s(key, kt[5]); 27 n2s(key, kt[6]); 28 n2s(key, kt[7]); 29 30 kf = kt; 31 kt += 8; 32 for (i = 0; i < 6; i++) { 33 r2 = kf[1]; 34 r1 = kf[2]; 35 *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; 36 r0 = kf[3]; 37 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 38 r1 = kf[4]; 39 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 40 r0 = kf[5]; 41 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 42 r1 = kf[6]; 43 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 44 r0 = kf[7]; 45 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 46 r1 = kf[0]; 47 if (i >= 5) 48 break; 49 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 50 *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; 51 kf += 8; 52 } 53 } 54 55 void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) 56 { 57 int r; 58 register IDEA_INT *fp, *tp, t; 59 60 tp = &(dk->data[0][0]); 61 fp = &(ek->data[8][0]); 62 for (r = 0; r < 9; r++) { 63 *(tp++) = inverse(fp[0]); 64 *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); 65 *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); 66 *(tp++) = inverse(fp[3]); 67 if (r == 8) 68 break; 69 fp -= 6; 70 *(tp++) = fp[4]; 71 *(tp++) = fp[5]; 72 } 73 74 tp = &(dk->data[0][0]); 75 t = tp[1]; 76 tp[1] = tp[2]; 77 tp[2] = t; 78 79 t = tp[49]; 80 tp[49] = tp[50]; 81 tp[50] = t; 82 } 83 84 /* taken directly from the 'paper' I'll have a look at it later */ 85 static IDEA_INT inverse(unsigned int xin) 86 { 87 int32_t n1, n2, q, r, b1, b2, t; 88 89 if (xin == 0) 90 b2 = 0; 91 else { 92 n1 = 0x10001; 93 n2 = xin; 94 b2 = 1; 95 b1 = 0; 96 97 do { 98 r = (n1 % n2); 99 q = (n1 - r) / n2; 100 if (r == 0) { 101 if (b2 < 0) 102 b2 = 0x10001 + b2; 103 } else { 104 n1 = n2; 105 n2 = r; 106 t = b2; 107 b2 = b1 - q * b2; 108 b1 = t; 109 } 110 } while (r != 0); 111 } 112 return ((IDEA_INT) b2); 113 } 114