Merge from vendor branch FILE:
[dragonfly.git] / crypto / openssh-3.9p1 / acss.c
1 /*      $Id: acss.c,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */
2 /*
3  * Copyright (c) 2004 The OpenBSD project
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include "includes.h"
19 #include <openssl/evp.h>
20
21 #if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L)
22
23 #include "acss.h"
24
25 /* decryption sbox */
26 static unsigned char sboxdec[] = {
27         0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, 
28         0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, 
29         0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, 
30         0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, 
31         0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, 
32         0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, 
33         0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, 
34         0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, 
35         0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, 
36         0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, 
37         0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, 
38         0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, 
39         0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, 
40         0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, 
41         0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, 
42         0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, 
43         0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, 
44         0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, 
45         0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, 
46         0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, 
47         0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, 
48         0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, 
49         0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, 
50         0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, 
51         0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, 
52         0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, 
53         0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, 
54         0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, 
55         0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, 
56         0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, 
57         0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, 
58         0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
59 };
60
61 /* encryption sbox */
62 static unsigned char sboxenc[] = {
63         0x33, 0x3b, 0x73, 0x15, 0x53, 0x5b, 0x13, 0x75,
64         0x3d, 0x35, 0x7d, 0x1b, 0x5d, 0x55, 0x1d, 0x7b,
65         0x67, 0x6f, 0x27, 0x81, 0xc7, 0xcf, 0x87, 0x21,
66         0x69, 0x61, 0x29, 0x8f, 0xc9, 0xc1, 0x89, 0x2f,
67         0xe3, 0xeb, 0xa3, 0x05, 0x43, 0x4b, 0x03, 0xa5,
68         0xed, 0xe5, 0xad, 0x0b, 0x4d, 0x45, 0x0d, 0xab,
69         0xea, 0xe2, 0xaa, 0x00, 0x4a, 0x42, 0x0a, 0xa0,
70         0xe8, 0xe0, 0xa8, 0x02, 0x48, 0x40, 0x08, 0xa2,
71         0x3e, 0x36, 0x7e, 0x14, 0x5e, 0x56, 0x1e, 0x74,
72         0x3c, 0x34, 0x7c, 0x16, 0x5c, 0x54, 0x1c, 0x76,
73         0x6a, 0x62, 0x2a, 0x80, 0xca, 0xc2, 0x8a, 0x20,
74         0x68, 0x60, 0x28, 0x82, 0xc8, 0xc0, 0x88, 0x22,
75         0xee, 0xe6, 0xae, 0x04, 0x4e, 0x46, 0x0e, 0xa4,
76         0xec, 0xe4, 0xac, 0x06, 0x4c, 0x44, 0x0c, 0xa6,
77         0xe7, 0xef, 0xa7, 0x01, 0x47, 0x4f, 0x07, 0xa1,
78         0xe9, 0xe1, 0xa9, 0x0f, 0x49, 0x41, 0x09, 0xaf,
79         0x63, 0x6b, 0x23, 0x85, 0xc3, 0xcb, 0x83, 0x25,
80         0x6d, 0x65, 0x2d, 0x8b, 0xcd, 0xc5, 0x8d, 0x2b,
81         0x37, 0x3f, 0x77, 0x11, 0x57, 0x5f, 0x17, 0x71,
82         0x39, 0x31, 0x79, 0x1f, 0x59, 0x51, 0x19, 0x7f,
83         0xb3, 0xbb, 0xf3, 0x95, 0xd3, 0xdb, 0x93, 0xf5,
84         0xbd, 0xb5, 0xfd, 0x9b, 0xdd, 0xd5, 0x9d, 0xfb,
85         0xba, 0xb2, 0xfa, 0x90, 0xda, 0xd2, 0x9a, 0xf0,
86         0xb8, 0xb0, 0xf8, 0x92, 0xd8, 0xd0, 0x98, 0xf2,
87         0x6e, 0x66, 0x2e, 0x84, 0xce, 0xc6, 0x8e, 0x24,
88         0x6c, 0x64, 0x2c, 0x86, 0xcc, 0xc4, 0x8c, 0x26,
89         0x3a, 0x32, 0x7a, 0x10, 0x5a, 0x52, 0x1a, 0x70,
90         0x38, 0x30, 0x78, 0x12, 0x58, 0x50, 0x18, 0x72,
91         0xbe, 0xb6, 0xfe, 0x94, 0xde, 0xd6, 0x9e, 0xf4,
92         0xbc, 0xb4, 0xfc, 0x96, 0xdc, 0xd4, 0x9c, 0xf6,
93         0xb7, 0xbf, 0xf7, 0x91, 0xd7, 0xdf, 0x97, 0xf1,
94         0xb9, 0xb1, 0xf9, 0x9f, 0xd9, 0xd1, 0x99, 0xff
95 };
96
97 static unsigned char reverse[] = {
98         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
99         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
100         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
101         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
102         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
103         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
104         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
105         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
106         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
107         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
108         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
109         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
110         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
111         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
112         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
113         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
114         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
115         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
116         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
117         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
118         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
119         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
120         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
121         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
122         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
123         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
124         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
125         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
126         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
127         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
128         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
129         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 
130 };
131
132 /*
133  * Two linear feedback shift registers are used:
134  *
135  * lfsr17:  polynomial of degree 17, primitive modulo 2 (listed in Schneier)
136  *          x^15 + x + 1
137  * lfsr25:  polynomial of degree 25, not know if primitive modulo 2
138  *          x^13 + x^5 + x^4 + x^1 + 1
139  *
140  * Output bits are discarded, instead the feedback bits are added to produce
141  * the cipher stream.  Depending on the mode, feedback bytes may be inverted
142  * bit-wise before addition.
143  *
144  * The lfsrs are seeded with bytes from the raw key:
145  *
146  * lfsr17:  byte 0[0:7] at bit 9
147  *          byte 1[0:7] at bit 0
148  *
149  * lfsr25:  byte 2[0:4] at bit 16
150  *          byte 2[5:7] at bit 22
151  *          byte 3[0:7] at bit 8
152  *          byte 4[0:7] at bit 0
153  *
154  * To prevent 0 cycles, 1's are inject at bit 8 in lfrs17 and bit 21 in
155  * lfsr25.
156  *
157  */
158
159 int
160 acss(ACSS_KEY *key, unsigned long len, const unsigned char *in,
161     unsigned char *out)
162 {
163         unsigned long i;
164         unsigned long lfsr17tmp, lfsr25tmp, lfsrsumtmp;
165
166         lfsrsumtmp = lfsr17tmp = lfsr25tmp = 0;
167
168         /* keystream is sum of lfsrs */
169         for (i = 0; i < len; i++) {
170                 lfsr17tmp = key->lfsr17 ^ (key->lfsr17 >> 14);
171                 key->lfsr17 = (key->lfsr17 >> 8)
172                         ^ (lfsr17tmp << 9)
173                         ^ (lfsr17tmp << 12)
174                         ^ (lfsr17tmp << 15);
175                 key->lfsr17 &= 0x1ffff; /* 17 bit LFSR */
176
177                 lfsr25tmp = key->lfsr25
178                         ^ (key->lfsr25 >> 3)
179                         ^ (key->lfsr25 >> 4)
180                         ^ (key->lfsr25 >> 12);
181                 key->lfsr25 = (key->lfsr25 >> 8) ^ (lfsr25tmp << 17);
182                 key->lfsr25 &= 0x1ffffff;       /* 25 bit LFSR */
183
184                 lfsrsumtmp = key->lfsrsum;
185
186                 /* addition */
187                 switch (key->mode) {
188                 case ACSS_AUTHENTICATE:
189                 case ACSS_DATA:
190                         key->lfsrsum = 0xff & ~(key->lfsr17 >> 9);
191                         key->lfsrsum += key->lfsr25 >> 17;
192                         break;
193                 case ACSS_SESSIONKEY:
194                         key->lfsrsum = key->lfsr17 >> 9;
195                         key->lfsrsum += key->lfsr25 >> 17;
196                         break;
197                 case ACSS_TITLEKEY:
198                         key->lfsrsum = key->lfsr17 >> 9;
199                         key->lfsrsum += 0xff & ~(key->lfsr25 >> 17);
200                         break;
201                 default:
202                         return 1;
203                 }
204                 key->lfsrsum += (lfsrsumtmp >> 8);
205
206                 if (key->encrypt) {
207                         out[i] = sboxenc[(in[i] ^ key->lfsrsum) & 0xff];
208                 } else {
209                         out[i] = (sboxdec[in[i]] ^ key->lfsrsum) & 0xff;
210                 }
211         }
212
213         return 0;
214 }
215
216 static void
217 acss_seed(ACSS_KEY *key)
218 {
219         int i;
220
221         /* if available, mangle with subkey */
222         if (key->subkey_avilable) {
223                 for (i = 0; i < ACSS_KEYSIZE; i++)
224                         key->seed[i] = reverse[key->data[i] ^ key->subkey[i]];
225         } else {
226                 for (i = 0; i < ACSS_KEYSIZE; i++)
227                         key->seed[i] = reverse[key->data[i]];
228         }
229
230         /* seed lfsrs */
231         key->lfsr17 = key->seed[1]
232                 | (key->seed[0] << 9)
233                 | (1 << 8);     /* inject 1 at bit 9 */
234         key->lfsr25 = key->seed[4]
235                 | (key->seed[3] << 8)
236                 | ((key->seed[2] & 0x1f) << 16)
237                 | ((key->seed[2] & 0xe0) << 17)
238                         | (1 << 21);    /* inject 1 at bit 22 */
239
240         key->lfsrsum = 0;
241 }
242
243 void
244 acss_setkey(ACSS_KEY *key, const unsigned char *data, int enc, int mode)
245 {
246         memcpy(key->data, data, sizeof(key->data));
247         memset(key->subkey, 0, sizeof(key->subkey));
248
249         if (enc != -1)
250                 key->encrypt = enc;
251         key->mode = mode;
252         key->subkey_avilable = 0;
253
254         acss_seed(key);
255 }
256
257 void
258 acss_setsubkey(ACSS_KEY *key, const unsigned char *subkey)
259 {
260         memcpy(key->subkey, subkey, sizeof(key->subkey));
261         key->subkey_avilable = 1;
262         acss_seed(key);
263 }
264 #endif