xref: /openssl/crypto/idea/i_skey.c (revision 33388b44)
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 "internal/deprecated.h"
16 
17 #include <openssl/idea.h>
18 #include "idea_local.h"
19 
20 static IDEA_INT inverse(unsigned int xin);
IDEA_set_encrypt_key(const unsigned char * key,IDEA_KEY_SCHEDULE * ks)21 void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
22 {
23     int i;
24     register IDEA_INT *kt, *kf, r0, r1, r2;
25 
26     kt = &(ks->data[0][0]);
27     n2s(key, kt[0]);
28     n2s(key, kt[1]);
29     n2s(key, kt[2]);
30     n2s(key, kt[3]);
31     n2s(key, kt[4]);
32     n2s(key, kt[5]);
33     n2s(key, kt[6]);
34     n2s(key, kt[7]);
35 
36     kf = kt;
37     kt += 8;
38     for (i = 0; i < 6; i++) {
39         r2 = kf[1];
40         r1 = kf[2];
41         *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff;
42         r0 = kf[3];
43         *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
44         r1 = kf[4];
45         *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
46         r0 = kf[5];
47         *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
48         r1 = kf[6];
49         *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
50         r0 = kf[7];
51         *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
52         r1 = kf[0];
53         if (i >= 5)
54             break;
55         *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
56         *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff;
57         kf += 8;
58     }
59 }
60 
IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE * ek,IDEA_KEY_SCHEDULE * dk)61 void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
62 {
63     int r;
64     register IDEA_INT *fp, *tp, t;
65 
66     tp = &(dk->data[0][0]);
67     fp = &(ek->data[8][0]);
68     for (r = 0; r < 9; r++) {
69         *(tp++) = inverse(fp[0]);
70         *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff);
71         *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff);
72         *(tp++) = inverse(fp[3]);
73         if (r == 8)
74             break;
75         fp -= 6;
76         *(tp++) = fp[4];
77         *(tp++) = fp[5];
78     }
79 
80     tp = &(dk->data[0][0]);
81     t = tp[1];
82     tp[1] = tp[2];
83     tp[2] = t;
84 
85     t = tp[49];
86     tp[49] = tp[50];
87     tp[50] = t;
88 }
89 
90 /* taken directly from the 'paper' I'll have a look at it later */
inverse(unsigned int xin)91 static IDEA_INT inverse(unsigned int xin)
92 {
93     long n1, n2, q, r, b1, b2, t;
94 
95     if (xin == 0)
96         b2 = 0;
97     else {
98         n1 = 0x10001;
99         n2 = xin;
100         b2 = 1;
101         b1 = 0;
102 
103         do {
104             r = (n1 % n2);
105             q = (n1 - r) / n2;
106             if (r == 0) {
107                 if (b2 < 0)
108                     b2 = 0x10001 + b2;
109             } else {
110                 n1 = n2;
111                 n2 = r;
112                 t = b2;
113                 b2 = b1 - q * b2;
114                 b1 = t;
115             }
116         } while (r != 0);
117     }
118     return (IDEA_INT)b2;
119 }
120