11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci/* 111cb0ef41Sopenharmony_ci * IDEA low level APIs are deprecated for public use, but still ok for internal 121cb0ef41Sopenharmony_ci * use where we're using them to implement the higher level EVP interface, as is 131cb0ef41Sopenharmony_ci * the case here. 141cb0ef41Sopenharmony_ci */ 151cb0ef41Sopenharmony_ci#include "internal/deprecated.h" 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci#include <openssl/idea.h> 181cb0ef41Sopenharmony_ci#include "idea_local.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cistatic IDEA_INT inverse(unsigned int xin); 211cb0ef41Sopenharmony_civoid IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) 221cb0ef41Sopenharmony_ci{ 231cb0ef41Sopenharmony_ci int i; 241cb0ef41Sopenharmony_ci register IDEA_INT *kt, *kf, r0, r1, r2; 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci kt = &(ks->data[0][0]); 271cb0ef41Sopenharmony_ci n2s(key, kt[0]); 281cb0ef41Sopenharmony_ci n2s(key, kt[1]); 291cb0ef41Sopenharmony_ci n2s(key, kt[2]); 301cb0ef41Sopenharmony_ci n2s(key, kt[3]); 311cb0ef41Sopenharmony_ci n2s(key, kt[4]); 321cb0ef41Sopenharmony_ci n2s(key, kt[5]); 331cb0ef41Sopenharmony_ci n2s(key, kt[6]); 341cb0ef41Sopenharmony_ci n2s(key, kt[7]); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci kf = kt; 371cb0ef41Sopenharmony_ci kt += 8; 381cb0ef41Sopenharmony_ci for (i = 0; i < 6; i++) { 391cb0ef41Sopenharmony_ci r2 = kf[1]; 401cb0ef41Sopenharmony_ci r1 = kf[2]; 411cb0ef41Sopenharmony_ci *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; 421cb0ef41Sopenharmony_ci r0 = kf[3]; 431cb0ef41Sopenharmony_ci *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 441cb0ef41Sopenharmony_ci r1 = kf[4]; 451cb0ef41Sopenharmony_ci *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 461cb0ef41Sopenharmony_ci r0 = kf[5]; 471cb0ef41Sopenharmony_ci *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 481cb0ef41Sopenharmony_ci r1 = kf[6]; 491cb0ef41Sopenharmony_ci *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 501cb0ef41Sopenharmony_ci r0 = kf[7]; 511cb0ef41Sopenharmony_ci *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; 521cb0ef41Sopenharmony_ci r1 = kf[0]; 531cb0ef41Sopenharmony_ci if (i >= 5) 541cb0ef41Sopenharmony_ci break; 551cb0ef41Sopenharmony_ci *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; 561cb0ef41Sopenharmony_ci *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; 571cb0ef41Sopenharmony_ci kf += 8; 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_civoid IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) 621cb0ef41Sopenharmony_ci{ 631cb0ef41Sopenharmony_ci int r; 641cb0ef41Sopenharmony_ci register IDEA_INT *fp, *tp, t; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci tp = &(dk->data[0][0]); 671cb0ef41Sopenharmony_ci fp = &(ek->data[8][0]); 681cb0ef41Sopenharmony_ci for (r = 0; r < 9; r++) { 691cb0ef41Sopenharmony_ci *(tp++) = inverse(fp[0]); 701cb0ef41Sopenharmony_ci *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); 711cb0ef41Sopenharmony_ci *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); 721cb0ef41Sopenharmony_ci *(tp++) = inverse(fp[3]); 731cb0ef41Sopenharmony_ci if (r == 8) 741cb0ef41Sopenharmony_ci break; 751cb0ef41Sopenharmony_ci fp -= 6; 761cb0ef41Sopenharmony_ci *(tp++) = fp[4]; 771cb0ef41Sopenharmony_ci *(tp++) = fp[5]; 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci tp = &(dk->data[0][0]); 811cb0ef41Sopenharmony_ci t = tp[1]; 821cb0ef41Sopenharmony_ci tp[1] = tp[2]; 831cb0ef41Sopenharmony_ci tp[2] = t; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci t = tp[49]; 861cb0ef41Sopenharmony_ci tp[49] = tp[50]; 871cb0ef41Sopenharmony_ci tp[50] = t; 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci/* taken directly from the 'paper' I'll have a look at it later */ 911cb0ef41Sopenharmony_cistatic IDEA_INT inverse(unsigned int xin) 921cb0ef41Sopenharmony_ci{ 931cb0ef41Sopenharmony_ci long n1, n2, q, r, b1, b2, t; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci if (xin == 0) 961cb0ef41Sopenharmony_ci b2 = 0; 971cb0ef41Sopenharmony_ci else { 981cb0ef41Sopenharmony_ci n1 = 0x10001; 991cb0ef41Sopenharmony_ci n2 = xin; 1001cb0ef41Sopenharmony_ci b2 = 1; 1011cb0ef41Sopenharmony_ci b1 = 0; 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci do { 1041cb0ef41Sopenharmony_ci r = (n1 % n2); 1051cb0ef41Sopenharmony_ci q = (n1 - r) / n2; 1061cb0ef41Sopenharmony_ci if (r == 0) { 1071cb0ef41Sopenharmony_ci if (b2 < 0) 1081cb0ef41Sopenharmony_ci b2 = 0x10001 + b2; 1091cb0ef41Sopenharmony_ci } else { 1101cb0ef41Sopenharmony_ci n1 = n2; 1111cb0ef41Sopenharmony_ci n2 = r; 1121cb0ef41Sopenharmony_ci t = b2; 1131cb0ef41Sopenharmony_ci b2 = b1 - q * b2; 1141cb0ef41Sopenharmony_ci b1 = t; 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci } while (r != 0); 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci return (IDEA_INT)b2; 1191cb0ef41Sopenharmony_ci} 120