xref: /netbsd-src/crypto/external/bsd/openssl/dist/crypto/idea/i_skey.c (revision 8fbed61efdd901c0e09614c9f45356aeeab23fe3)
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