~ubuntu-branches/ubuntu/lucid/openssh/lucid

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