1 /*
2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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 /*
11 * IDEA low level APIs are deprecated for public use, but still ok for internal
12 * use where we're using them to implement the higher level EVP interface, as is
13 * the case here.
14 */
15 #include <inttypes.h>
16 #include "internal/deprecated.h"
17
18 #include <openssl/idea.h>
19 #include "idea_local.h"
20
21 static IDEA_INT inverse(unsigned int xin);
IDEA_set_encrypt_key(const unsigned char * key,IDEA_KEY_SCHEDULE * ks)22 void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
23 {
24 int i;
25 register IDEA_INT *kt, *kf, r0, r1, r2;
26
27 kt = &(ks->data[0][0]);
28 n2s(key, kt[0]);
29 n2s(key, kt[1]);
30 n2s(key, kt[2]);
31 n2s(key, kt[3]);
32 n2s(key, kt[4]);
33 n2s(key, kt[5]);
34 n2s(key, kt[6]);
35 n2s(key, kt[7]);
36
37 kf = kt;
38 kt += 8;
39 for (i = 0; i < 6; i++) {
40 r2 = kf[1];
41 r1 = kf[2];
42 *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff;
43 r0 = kf[3];
44 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
45 r1 = kf[4];
46 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
47 r0 = kf[5];
48 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
49 r1 = kf[6];
50 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
51 r0 = kf[7];
52 *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
53 r1 = kf[0];
54 if (i >= 5)
55 break;
56 *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
57 *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff;
58 kf += 8;
59 }
60 }
61
IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE * ek,IDEA_KEY_SCHEDULE * dk)62 void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
63 {
64 int r;
65 register IDEA_INT *fp, *tp, t;
66
67 tp = &(dk->data[0][0]);
68 fp = &(ek->data[8][0]);
69 for (r = 0; r < 9; r++) {
70 *(tp++) = inverse(fp[0]);
71 *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff);
72 *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff);
73 *(tp++) = inverse(fp[3]);
74 if (r == 8)
75 break;
76 fp -= 6;
77 *(tp++) = fp[4];
78 *(tp++) = fp[5];
79 }
80
81 tp = &(dk->data[0][0]);
82 t = tp[1];
83 tp[1] = tp[2];
84 tp[2] = t;
85
86 t = tp[49];
87 tp[49] = tp[50];
88 tp[50] = t;
89 }
90
91 /* taken directly from the 'paper' I'll have a look at it later */
inverse(unsigned int xin)92 static IDEA_INT inverse(unsigned int xin)
93 {
94 int32_t n1, n2, q, r, b1, b2, t;
95
96 if (xin == 0)
97 b2 = 0;
98 else {
99 n1 = 0x10001;
100 n2 = xin;
101 b2 = 1;
102 b1 = 0;
103
104 do {
105 r = (n1 % n2);
106 q = (n1 - r) / n2;
107 if (r == 0) {
108 if (b2 < 0)
109 b2 = 0x10001 + b2;
110 } else {
111 n1 = n2;
112 n2 = r;
113 t = b2;
114 b2 = b1 - q * b2;
115 b1 = t;
116 }
117 } while (r != 0);
118 }
119 return (IDEA_INT)b2;
120 }
121