xref: /titanic_44/usr/src/uts/common/des/des_soft.c (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
27*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
31*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*
35*7c478bd9Sstevel@tonic-gate  * Warning!  Things are arranged very carefully in this file to
36*7c478bd9Sstevel@tonic-gate  * allow read-only data to be moved to the text segment.  The
37*7c478bd9Sstevel@tonic-gate  * various DES tables must appear before any function definitions
38*7c478bd9Sstevel@tonic-gate  * (this is arranged by including them immediately below) and partab
39*7c478bd9Sstevel@tonic-gate  * must also appear before and function definitions
40*7c478bd9Sstevel@tonic-gate  * This arrangement allows all data up through the first text to
41*7c478bd9Sstevel@tonic-gate  * be moved to text.
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /*
45*7c478bd9Sstevel@tonic-gate  * Fast (?) software implementation of DES
46*7c478bd9Sstevel@tonic-gate  * Has been seen going at 2000 bytes/sec on a Sun-2
47*7c478bd9Sstevel@tonic-gate  * Works on a VAX too.
48*7c478bd9Sstevel@tonic-gate  * Won't work without 8 bit chars and 32 bit longs
49*7c478bd9Sstevel@tonic-gate  */
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
52*7c478bd9Sstevel@tonic-gate #include <des/des.h>
53*7c478bd9Sstevel@tonic-gate #include <des/softdes.h>
54*7c478bd9Sstevel@tonic-gate #include <des/desdata.h>
55*7c478bd9Sstevel@tonic-gate #include <sys/debug.h>
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate static void des_setkey(u_char userkey[8], struct deskeydata *kd,
58*7c478bd9Sstevel@tonic-gate     unsigned int dir);
59*7c478bd9Sstevel@tonic-gate static void des_encrypt(u_char *data, struct deskeydata *kd);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate #define	btst(k, b)	(k[b >> 3] & (0x80 >> (b & 07)))
62*7c478bd9Sstevel@tonic-gate #define	BIT28	(1<<28)
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /*
65*7c478bd9Sstevel@tonic-gate  * Software encrypt or decrypt a block of data (multiple of 8 bytes)
66*7c478bd9Sstevel@tonic-gate  * Do the CBC ourselves if needed.
67*7c478bd9Sstevel@tonic-gate  */
68*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
69*7c478bd9Sstevel@tonic-gate int
_des_crypt(char * buf,size_t len,struct desparams * desp)70*7c478bd9Sstevel@tonic-gate _des_crypt(char *buf, size_t len, struct desparams *desp)
71*7c478bd9Sstevel@tonic-gate {
72*7c478bd9Sstevel@tonic-gate 	short i;
73*7c478bd9Sstevel@tonic-gate 	uint_t mode;
74*7c478bd9Sstevel@tonic-gate 	uint_t dir;
75*7c478bd9Sstevel@tonic-gate 	char nextiv[8];
76*7c478bd9Sstevel@tonic-gate 	struct deskeydata softkey;
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate 	mode = desp->des_mode;
79*7c478bd9Sstevel@tonic-gate 	dir = desp->des_dir;
80*7c478bd9Sstevel@tonic-gate 	des_setkey(desp->des_key, &softkey, dir);
81*7c478bd9Sstevel@tonic-gate 	while (len != 0) {
82*7c478bd9Sstevel@tonic-gate 		switch (mode) {
83*7c478bd9Sstevel@tonic-gate 		case CBC:
84*7c478bd9Sstevel@tonic-gate 			switch (dir) {
85*7c478bd9Sstevel@tonic-gate 			case ENCRYPT:
86*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < 8; i++)
87*7c478bd9Sstevel@tonic-gate 					buf[i] ^= desp->des_ivec[i];
88*7c478bd9Sstevel@tonic-gate 				des_encrypt((u_char *)buf, &softkey);
89*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < 8; i++)
90*7c478bd9Sstevel@tonic-gate 					desp->des_ivec[i] = buf[i];
91*7c478bd9Sstevel@tonic-gate 				break;
92*7c478bd9Sstevel@tonic-gate 			case DECRYPT:
93*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < 8; i++)
94*7c478bd9Sstevel@tonic-gate 					nextiv[i] = buf[i];
95*7c478bd9Sstevel@tonic-gate 				des_encrypt((u_char *)buf, &softkey);
96*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < 8; i++) {
97*7c478bd9Sstevel@tonic-gate 					buf[i] ^= desp->des_ivec[i];
98*7c478bd9Sstevel@tonic-gate 					desp->des_ivec[i] = nextiv[i];
99*7c478bd9Sstevel@tonic-gate 				}
100*7c478bd9Sstevel@tonic-gate 				break;
101*7c478bd9Sstevel@tonic-gate 			}
102*7c478bd9Sstevel@tonic-gate 			break;
103*7c478bd9Sstevel@tonic-gate 		case ECB:
104*7c478bd9Sstevel@tonic-gate 			des_encrypt((u_char *)buf, &softkey);
105*7c478bd9Sstevel@tonic-gate 			break;
106*7c478bd9Sstevel@tonic-gate 		}
107*7c478bd9Sstevel@tonic-gate 		buf += 8;
108*7c478bd9Sstevel@tonic-gate 		len -= 8;
109*7c478bd9Sstevel@tonic-gate 	}
110*7c478bd9Sstevel@tonic-gate 	return (1);
111*7c478bd9Sstevel@tonic-gate }
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate /*
115*7c478bd9Sstevel@tonic-gate  * Set the key and direction for an encryption operation
116*7c478bd9Sstevel@tonic-gate  * We build the 16 key entries here
117*7c478bd9Sstevel@tonic-gate  */
118*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
119*7c478bd9Sstevel@tonic-gate static void
des_setkey(u_char userkey[8],struct deskeydata * kd,unsigned int dir)120*7c478bd9Sstevel@tonic-gate des_setkey(u_char userkey[8], struct deskeydata *kd, unsigned int dir)
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate 	int32_t C, D;
123*7c478bd9Sstevel@tonic-gate 	short i;
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 	/*
126*7c478bd9Sstevel@tonic-gate 	 * First, generate C and D by permuting
127*7c478bd9Sstevel@tonic-gate 	 * the key. The low order bit of each
128*7c478bd9Sstevel@tonic-gate 	 * 8-bit char is not used, so C and D are only 28
129*7c478bd9Sstevel@tonic-gate 	 * bits apiece.
130*7c478bd9Sstevel@tonic-gate 	 */
131*7c478bd9Sstevel@tonic-gate 	{
132*7c478bd9Sstevel@tonic-gate 		short bit;
133*7c478bd9Sstevel@tonic-gate 		short *pcc = (short *)PC1_C, *pcd = (short *)PC1_D;
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 		C = D = 0;
136*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < 28; i++) {
137*7c478bd9Sstevel@tonic-gate 			C <<= 1;
138*7c478bd9Sstevel@tonic-gate 			D <<= 1;
139*7c478bd9Sstevel@tonic-gate 			bit = *pcc++;
140*7c478bd9Sstevel@tonic-gate 			if (btst(userkey, bit))
141*7c478bd9Sstevel@tonic-gate 				C |= 1;
142*7c478bd9Sstevel@tonic-gate 			bit = *pcd++;
143*7c478bd9Sstevel@tonic-gate 			if (btst(userkey, bit))
144*7c478bd9Sstevel@tonic-gate 				D |= 1;
145*7c478bd9Sstevel@tonic-gate 		}
146*7c478bd9Sstevel@tonic-gate 	}
147*7c478bd9Sstevel@tonic-gate 	/*
148*7c478bd9Sstevel@tonic-gate 	 * To generate Ki, rotate C and D according
149*7c478bd9Sstevel@tonic-gate 	 * to schedule and pick up a permutation
150*7c478bd9Sstevel@tonic-gate 	 * using PC2.
151*7c478bd9Sstevel@tonic-gate 	 */
152*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i++) {
153*7c478bd9Sstevel@tonic-gate 		chunk_t *c;
154*7c478bd9Sstevel@tonic-gate 		short j, k, bit;
155*7c478bd9Sstevel@tonic-gate 		int bbit;
156*7c478bd9Sstevel@tonic-gate 
157*7c478bd9Sstevel@tonic-gate 		/*
158*7c478bd9Sstevel@tonic-gate 		 * Do the "left shift" (rotate)
159*7c478bd9Sstevel@tonic-gate 		 * We know we always rotate by either 1 or 2 bits
160*7c478bd9Sstevel@tonic-gate 		 * the shifts table tells us if its 2
161*7c478bd9Sstevel@tonic-gate 		 */
162*7c478bd9Sstevel@tonic-gate 		C <<= 1;
163*7c478bd9Sstevel@tonic-gate 		if (C & BIT28)
164*7c478bd9Sstevel@tonic-gate 			C |= 1;
165*7c478bd9Sstevel@tonic-gate 		D <<= 1;
166*7c478bd9Sstevel@tonic-gate 		if (D & BIT28)
167*7c478bd9Sstevel@tonic-gate 			D |= 1;
168*7c478bd9Sstevel@tonic-gate 		if (shifts[i]) {
169*7c478bd9Sstevel@tonic-gate 			C <<= 1;
170*7c478bd9Sstevel@tonic-gate 			if (C & BIT28)
171*7c478bd9Sstevel@tonic-gate 				C |= 1;
172*7c478bd9Sstevel@tonic-gate 			D <<= 1;
173*7c478bd9Sstevel@tonic-gate 			if (D & BIT28)
174*7c478bd9Sstevel@tonic-gate 				D |= 1;
175*7c478bd9Sstevel@tonic-gate 		}
176*7c478bd9Sstevel@tonic-gate 		/*
177*7c478bd9Sstevel@tonic-gate 		 * get Ki. Note C and D are concatenated.
178*7c478bd9Sstevel@tonic-gate 		 */
179*7c478bd9Sstevel@tonic-gate 		bit = 0;
180*7c478bd9Sstevel@tonic-gate 		switch (dir) {
181*7c478bd9Sstevel@tonic-gate 		case ENCRYPT:
182*7c478bd9Sstevel@tonic-gate 			c = &kd->keyval[i];
183*7c478bd9Sstevel@tonic-gate 			break;
184*7c478bd9Sstevel@tonic-gate 		case DECRYPT:
185*7c478bd9Sstevel@tonic-gate 			c = &kd->keyval[15 - i];
186*7c478bd9Sstevel@tonic-gate 			break;
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate 		c->long0 = 0;
189*7c478bd9Sstevel@tonic-gate 		c->long1 = 0;
190*7c478bd9Sstevel@tonic-gate 		bbit = (1 << 5) << 24;
191*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < 4; j++) {
192*7c478bd9Sstevel@tonic-gate 			for (k = 0; k < 6; k++) {
193*7c478bd9Sstevel@tonic-gate 				if (C & (BIT28 >> PC2_C[bit]))
194*7c478bd9Sstevel@tonic-gate 					c->long0 |= bbit >> k;
195*7c478bd9Sstevel@tonic-gate 				if (D & (BIT28 >> PC2_D[bit]))
196*7c478bd9Sstevel@tonic-gate 					c->long1 |= bbit >> k;
197*7c478bd9Sstevel@tonic-gate 				bit++;
198*7c478bd9Sstevel@tonic-gate 			}
199*7c478bd9Sstevel@tonic-gate 			bbit >>= 8;
200*7c478bd9Sstevel@tonic-gate 		}
201*7c478bd9Sstevel@tonic-gate 	}
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate /*
207*7c478bd9Sstevel@tonic-gate  * Do an encryption operation
208*7c478bd9Sstevel@tonic-gate  * Much pain is taken (with preprocessor) to avoid loops so the compiler
209*7c478bd9Sstevel@tonic-gate  * can do address arithmetic instead of doing it at runtime.
210*7c478bd9Sstevel@tonic-gate  * Note that the byte-to-chunk conversion is necessary to guarantee
211*7c478bd9Sstevel@tonic-gate  * processor byte-order independence.
212*7c478bd9Sstevel@tonic-gate  */
213*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
214*7c478bd9Sstevel@tonic-gate static void
des_encrypt(u_char * data,struct deskeydata * kd)215*7c478bd9Sstevel@tonic-gate des_encrypt(u_char *data, struct deskeydata *kd)
216*7c478bd9Sstevel@tonic-gate {
217*7c478bd9Sstevel@tonic-gate 	chunk_t work1, work2;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	/*
220*7c478bd9Sstevel@tonic-gate 	 * Initial permutation
221*7c478bd9Sstevel@tonic-gate 	 * and byte to chunk conversion
222*7c478bd9Sstevel@tonic-gate 	 */
223*7c478bd9Sstevel@tonic-gate 	{
224*7c478bd9Sstevel@tonic-gate 		const uint32_t *lp;
225*7c478bd9Sstevel@tonic-gate 		uint32_t l0, l1, w;
226*7c478bd9Sstevel@tonic-gate 		short i, pbit;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 		work1.byte0 = data[0];
229*7c478bd9Sstevel@tonic-gate 		work1.byte1 = data[1];
230*7c478bd9Sstevel@tonic-gate 		work1.byte2 = data[2];
231*7c478bd9Sstevel@tonic-gate 		work1.byte3 = data[3];
232*7c478bd9Sstevel@tonic-gate 		work1.byte4 = data[4];
233*7c478bd9Sstevel@tonic-gate 		work1.byte5 = data[5];
234*7c478bd9Sstevel@tonic-gate 		work1.byte6 = data[6];
235*7c478bd9Sstevel@tonic-gate 		work1.byte7 = data[7];
236*7c478bd9Sstevel@tonic-gate 		l0 = l1 = 0;
237*7c478bd9Sstevel@tonic-gate 		w = work1.long0;
238*7c478bd9Sstevel@tonic-gate 		for (lp = &longtab[0], i = 0; i < 32; i++) {
239*7c478bd9Sstevel@tonic-gate 			if (w & *lp++) {
240*7c478bd9Sstevel@tonic-gate 				pbit = IPtab[i];
241*7c478bd9Sstevel@tonic-gate 				if (pbit < 32)
242*7c478bd9Sstevel@tonic-gate 					l0 |= longtab[pbit];
243*7c478bd9Sstevel@tonic-gate 				else
244*7c478bd9Sstevel@tonic-gate 					l1 |= longtab[pbit-32];
245*7c478bd9Sstevel@tonic-gate 			}
246*7c478bd9Sstevel@tonic-gate 		}
247*7c478bd9Sstevel@tonic-gate 		w = work1.long1;
248*7c478bd9Sstevel@tonic-gate 		for (lp = &longtab[0], i = 32; i < 64; i++) {
249*7c478bd9Sstevel@tonic-gate 			if (w & *lp++) {
250*7c478bd9Sstevel@tonic-gate 				pbit = IPtab[i];
251*7c478bd9Sstevel@tonic-gate 				if (pbit < 32)
252*7c478bd9Sstevel@tonic-gate 					l0 |= longtab[pbit];
253*7c478bd9Sstevel@tonic-gate 				else
254*7c478bd9Sstevel@tonic-gate 					l1 |= longtab[pbit-32];
255*7c478bd9Sstevel@tonic-gate 			}
256*7c478bd9Sstevel@tonic-gate 		}
257*7c478bd9Sstevel@tonic-gate 		work2.long0 = l0;
258*7c478bd9Sstevel@tonic-gate 		work2.long1 = l1;
259*7c478bd9Sstevel@tonic-gate 	}
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate /*
262*7c478bd9Sstevel@tonic-gate  * Expand 8 bits of 32 bit R to 48 bit R
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
265*7c478bd9Sstevel@tonic-gate #define	do_R_to_ER(op, b) {					\
266*7c478bd9Sstevel@tonic-gate 	struct R_to_ER *p =					\
267*7c478bd9Sstevel@tonic-gate 	    (struct R_to_ER *)&R_to_ER_tab[b][R.byte##b];	\
268*7c478bd9Sstevel@tonic-gate 	e0 op p->l0;						\
269*7c478bd9Sstevel@tonic-gate 	e1 op p->l1;						\
270*7c478bd9Sstevel@tonic-gate }
271*7c478bd9Sstevel@tonic-gate #else
272*7c478bd9Sstevel@tonic-gate #define	do_R_to_ER(op, b)	{				\
273*7c478bd9Sstevel@tonic-gate 	/*CSTYLED*/						\
274*7c478bd9Sstevel@tonic-gate 	struct R_to_ER *p = &R_to_ER_tab[b][R.byte/**/b];	\
275*7c478bd9Sstevel@tonic-gate 	e0 op p->l0;						\
276*7c478bd9Sstevel@tonic-gate 	e1 op p->l1;						\
277*7c478bd9Sstevel@tonic-gate }
278*7c478bd9Sstevel@tonic-gate #endif
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate /*
281*7c478bd9Sstevel@tonic-gate  * Inner part of the algorithm:
282*7c478bd9Sstevel@tonic-gate  * Expand R from 32 to 48 bits; xor key value;
283*7c478bd9Sstevel@tonic-gate  * apply S boxes; permute 32 bits of output
284*7c478bd9Sstevel@tonic-gate  */
285*7c478bd9Sstevel@tonic-gate #define	do_F(iter, inR, outR) 	{			\
286*7c478bd9Sstevel@tonic-gate 	chunk_t R, ER;					\
287*7c478bd9Sstevel@tonic-gate 	u_int e0, e1;					\
288*7c478bd9Sstevel@tonic-gate 	R.long0 = inR;					\
289*7c478bd9Sstevel@tonic-gate 	/*CSTYLED*/					\
290*7c478bd9Sstevel@tonic-gate 	do_R_to_ER(=,0);				\
291*7c478bd9Sstevel@tonic-gate 	/*CSTYLED*/					\
292*7c478bd9Sstevel@tonic-gate 	do_R_to_ER(|=,1);				\
293*7c478bd9Sstevel@tonic-gate 	/*CSTYLED*/					\
294*7c478bd9Sstevel@tonic-gate 	do_R_to_ER(|=,2);				\
295*7c478bd9Sstevel@tonic-gate 	/*CSTYLED*/					\
296*7c478bd9Sstevel@tonic-gate 	do_R_to_ER(|=,3);				\
297*7c478bd9Sstevel@tonic-gate 	ER.long0 = e0 ^ kd->keyval[iter].long0;		\
298*7c478bd9Sstevel@tonic-gate 	ER.long1 = e1 ^ kd->keyval[iter].long1;		\
299*7c478bd9Sstevel@tonic-gate 	R.long0 =					\
300*7c478bd9Sstevel@tonic-gate 		S_tab[0][ER.byte0] +			\
301*7c478bd9Sstevel@tonic-gate 		S_tab[1][ER.byte1] +			\
302*7c478bd9Sstevel@tonic-gate 		S_tab[2][ER.byte2] +			\
303*7c478bd9Sstevel@tonic-gate 		S_tab[3][ER.byte3] +			\
304*7c478bd9Sstevel@tonic-gate 		S_tab[4][ER.byte4] +			\
305*7c478bd9Sstevel@tonic-gate 		S_tab[5][ER.byte5] +			\
306*7c478bd9Sstevel@tonic-gate 		S_tab[6][ER.byte6] +			\
307*7c478bd9Sstevel@tonic-gate 		S_tab[7][ER.byte7]; 			\
308*7c478bd9Sstevel@tonic-gate 	outR =						\
309*7c478bd9Sstevel@tonic-gate 		P_tab[0][R.byte0] +			\
310*7c478bd9Sstevel@tonic-gate 		P_tab[1][R.byte1] +			\
311*7c478bd9Sstevel@tonic-gate 		P_tab[2][R.byte2] +			\
312*7c478bd9Sstevel@tonic-gate 		P_tab[3][R.byte3]; 			\
313*7c478bd9Sstevel@tonic-gate }
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate /*
316*7c478bd9Sstevel@tonic-gate  * Do a cipher step
317*7c478bd9Sstevel@tonic-gate  * Apply inner part; do xor and exchange of 32 bit parts
318*7c478bd9Sstevel@tonic-gate  */
319*7c478bd9Sstevel@tonic-gate #define	cipher(iter, inR, inL, outR, outL)	{	\
320*7c478bd9Sstevel@tonic-gate 	do_F(iter, inR, outR);				\
321*7c478bd9Sstevel@tonic-gate 	outR ^= inL;					\
322*7c478bd9Sstevel@tonic-gate 	outL = inR;					\
323*7c478bd9Sstevel@tonic-gate }
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	/*
326*7c478bd9Sstevel@tonic-gate 	 * Apply the 16 ciphering steps
327*7c478bd9Sstevel@tonic-gate 	 */
328*7c478bd9Sstevel@tonic-gate 	{
329*7c478bd9Sstevel@tonic-gate 		u_int r0, l0, r1, l1;
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 		l0 = work2.long0;
332*7c478bd9Sstevel@tonic-gate 		r0 = work2.long1;
333*7c478bd9Sstevel@tonic-gate 		cipher(0, r0, l0, r1, l1);
334*7c478bd9Sstevel@tonic-gate 		cipher(1, r1, l1, r0, l0);
335*7c478bd9Sstevel@tonic-gate 		cipher(2, r0, l0, r1, l1);
336*7c478bd9Sstevel@tonic-gate 		cipher(3, r1, l1, r0, l0);
337*7c478bd9Sstevel@tonic-gate 		cipher(4, r0, l0, r1, l1);
338*7c478bd9Sstevel@tonic-gate 		cipher(5, r1, l1, r0, l0);
339*7c478bd9Sstevel@tonic-gate 		cipher(6, r0, l0, r1, l1);
340*7c478bd9Sstevel@tonic-gate 		cipher(7, r1, l1, r0, l0);
341*7c478bd9Sstevel@tonic-gate 		cipher(8, r0, l0, r1, l1);
342*7c478bd9Sstevel@tonic-gate 		cipher(9, r1, l1, r0, l0);
343*7c478bd9Sstevel@tonic-gate 		cipher(10, r0, l0, r1, l1);
344*7c478bd9Sstevel@tonic-gate 		cipher(11, r1, l1, r0, l0);
345*7c478bd9Sstevel@tonic-gate 		cipher(12, r0, l0, r1, l1);
346*7c478bd9Sstevel@tonic-gate 		cipher(13, r1, l1, r0, l0);
347*7c478bd9Sstevel@tonic-gate 		cipher(14, r0, l0, r1, l1);
348*7c478bd9Sstevel@tonic-gate 		cipher(15, r1, l1, r0, l0);
349*7c478bd9Sstevel@tonic-gate 		work1.long0 = r0;
350*7c478bd9Sstevel@tonic-gate 		work1.long1 = l0;
351*7c478bd9Sstevel@tonic-gate 	}
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate 	/*
354*7c478bd9Sstevel@tonic-gate 	 * Final permutation
355*7c478bd9Sstevel@tonic-gate 	 * and chunk to byte conversion
356*7c478bd9Sstevel@tonic-gate 	 */
357*7c478bd9Sstevel@tonic-gate 	{
358*7c478bd9Sstevel@tonic-gate 		const uint32_t *lp;
359*7c478bd9Sstevel@tonic-gate 		uint32_t l0, l1, w;
360*7c478bd9Sstevel@tonic-gate 		short i, pbit;
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 		l0 = l1 = 0;
363*7c478bd9Sstevel@tonic-gate 		w = work1.long0;
364*7c478bd9Sstevel@tonic-gate 		for (lp = &longtab[0], i = 0; i < 32; i++) {
365*7c478bd9Sstevel@tonic-gate 			if (w & *lp++) {
366*7c478bd9Sstevel@tonic-gate 				pbit = FPtab[i];
367*7c478bd9Sstevel@tonic-gate 				if (pbit < 32)
368*7c478bd9Sstevel@tonic-gate 					l0 |= longtab[pbit];
369*7c478bd9Sstevel@tonic-gate 				else
370*7c478bd9Sstevel@tonic-gate 					l1 |= longtab[pbit-32];
371*7c478bd9Sstevel@tonic-gate 			}
372*7c478bd9Sstevel@tonic-gate 		}
373*7c478bd9Sstevel@tonic-gate 		w = work1.long1;
374*7c478bd9Sstevel@tonic-gate 		for (lp = &longtab[0], i = 32; i < 64; i++) {
375*7c478bd9Sstevel@tonic-gate 			if (w & *lp++) {
376*7c478bd9Sstevel@tonic-gate 				pbit = FPtab[i];
377*7c478bd9Sstevel@tonic-gate 				if (pbit < 32)
378*7c478bd9Sstevel@tonic-gate 					l0 |= longtab[pbit];
379*7c478bd9Sstevel@tonic-gate 				else
380*7c478bd9Sstevel@tonic-gate 					l1 |= longtab[pbit-32];
381*7c478bd9Sstevel@tonic-gate 			}
382*7c478bd9Sstevel@tonic-gate 		}
383*7c478bd9Sstevel@tonic-gate 		work2.long0 = l0;
384*7c478bd9Sstevel@tonic-gate 		work2.long1 = l1;
385*7c478bd9Sstevel@tonic-gate 	}
386*7c478bd9Sstevel@tonic-gate 	data[0] = work2.byte0;
387*7c478bd9Sstevel@tonic-gate 	data[1] = work2.byte1;
388*7c478bd9Sstevel@tonic-gate 	data[2] = work2.byte2;
389*7c478bd9Sstevel@tonic-gate 	data[3] = work2.byte3;
390*7c478bd9Sstevel@tonic-gate 	data[4] = work2.byte4;
391*7c478bd9Sstevel@tonic-gate 	data[5] = work2.byte5;
392*7c478bd9Sstevel@tonic-gate 	data[6] = work2.byte6;
393*7c478bd9Sstevel@tonic-gate 	data[7] = work2.byte7;
394*7c478bd9Sstevel@tonic-gate }
395