xref: /csrg-svn/old/berknet/nbs.c (revision 8190)
1*8190Smckusick static char sccsid[] = "@(#)nbs.c	4.1	(Berkeley)	09/12/82";
2*8190Smckusick 
3*8190Smckusick # include <stdio.h>
4*8190Smckusick /* sccs id variable */
5*8190Smckusick static char *nbs_sid = "@(#)nbs.c	1.2";
6*8190Smckusick 
7*8190Smckusick /* file nbs.c
8*8190Smckusick    This file has the necessary procedures to use the NBS algorithm
9*8190Smckusick    to encrypt and decrypt strings of arbitrary length.
10*8190Smckusick 
11*8190Smckusick    Basically
12*8190Smckusick 
13*8190Smckusick 		ciphertext = nbsencrypt(cleartext,secretkey,ciphertext);
14*8190Smckusick 
15*8190Smckusick    yields a string ciphertext from string cleartext using
16*8190Smckusick    the secret string secretkey.
17*8190Smckusick    Then
18*8190Smckusick 
19*8190Smckusick 		cleartext = nbsdecrypt(ciphertext,secretkey,cleartext);
20*8190Smckusick 
21*8190Smckusick    yields the original string cleartext IF the string secretkey
22*8190Smckusick    is the same for both calls.
23*8190Smckusick    The third parameter is filled with the result of the call-
24*8190Smckusick    it must be (11/8)*size(firstarg).
25*8190Smckusick    The first and third areguments must be different.
26*8190Smckusick    The cleartext must be ASCII - the top eighth bit is ignored,
27*8190Smckusick    so binary data won't work.
28*8190Smckusick    The plaintext is broken into 8 character sections,
29*8190Smckusick    encrypted, and concatenated separated by $'s to make the ciphertext.
30*8190Smckusick    The first 8 letter section uses the secretkey, subsequent
31*8190Smckusick    sections use the cleartext of the previous section as
32*8190Smckusick    the key.
33*8190Smckusick    Thus the ciphertext depends on itself, except for
34*8190Smckusick    the first section, which depends on the key.
35*8190Smckusick    This means that sections of the ciphertext, except the first,
36*8190Smckusick    may not stand alone.
37*8190Smckusick    Only the first 8 characters of the key matter.
38*8190Smckusick */
39*8190Smckusick char *deblknot(), *deblkclr();
40*8190Smckusick char *nbs8decrypt(), *nbs8encrypt();
41*8190Smckusick static char	E[48];
42*8190Smckusick char e[];
nbsencrypt(str,key,result)43*8190Smckusick char *nbsencrypt(str,key,result)
44*8190Smckusick   char *result;
45*8190Smckusick   char *str, *key; {
46*8190Smckusick 	static char buf[20],oldbuf[20];
47*8190Smckusick 	register int j;
48*8190Smckusick 	result[0] = 0;
49*8190Smckusick 	strcpy(oldbuf,key);
50*8190Smckusick 	while(*str){
51*8190Smckusick 		for(j=0;j<10;j++)buf[j] = 0;
52*8190Smckusick 		for(j=0;j<8 && *str;j++)buf[j] = *str++;
53*8190Smckusick 		strcat(result,nbs8encrypt(buf,oldbuf));
54*8190Smckusick 		strcat(result,"$");
55*8190Smckusick 		strcpy(oldbuf,buf);
56*8190Smckusick 		}
57*8190Smckusick 	return(result);
58*8190Smckusick 	}
nbsdecrypt(cpt,key,result)59*8190Smckusick char *nbsdecrypt(cpt,key,result)
60*8190Smckusick   char *result;
61*8190Smckusick   char *cpt,*key; {
62*8190Smckusick 	char *s;
63*8190Smckusick 	char c,oldbuf[20];
64*8190Smckusick 	result[0] = 0;
65*8190Smckusick 	strcpy(oldbuf,key);
66*8190Smckusick 	while(*cpt){
67*8190Smckusick 		for(s = cpt;*s && *s != '$';s++);
68*8190Smckusick 		c = *s;
69*8190Smckusick 		*s = 0;
70*8190Smckusick 		strcpy(oldbuf,nbs8decrypt(cpt,oldbuf));
71*8190Smckusick 		strcat(result,oldbuf);
72*8190Smckusick 		if(c == 0)break;
73*8190Smckusick 		cpt = s + 1;
74*8190Smckusick 		}
75*8190Smckusick 	return(result);
76*8190Smckusick 	}
77*8190Smckusick /* make key to be sent across the network */
makeuukey(skey,sn,mch)78*8190Smckusick makeuukey(skey,sn,mch)
79*8190Smckusick char *skey, *sn, mch;
80*8190Smckusick {
81*8190Smckusick 	skey[0] = mch;
82*8190Smckusick 	skey[1] = 0;
83*8190Smckusick 	strcat(skey,sn);
84*8190Smckusick }
85*8190Smckusick 
86*8190Smckusick /* all other calls are private */
87*8190Smckusick /*
88*8190Smckusick char _sobuf[BUFSIZ];
89*8190Smckusick testing(){
90*8190Smckusick 	static char res[BUFSIZ];
91*8190Smckusick 	char *s;
92*8190Smckusick 	char str[BUFSIZ];
93*8190Smckusick 	setbuf(stdout,_sobuf);
94*8190Smckusick 	while(!feof(stdin)){
95*8190Smckusick 		fprintf(stderr,"String:\n");
96*8190Smckusick 		fgets(str,BUFSIZ,stdin);
97*8190Smckusick 		if(feof(stdin))break;
98*8190Smckusick 		strcat(str,"\n");
99*8190Smckusick 		s = nbsencrypt(str,"hellothere",res);
100*8190Smckusick 		fprintf(stderr,"encrypted:\n%s\n",s);
101*8190Smckusick 		fprintf(stderr,"decrypted:\n");
102*8190Smckusick 		printf("%s",nbsdecrypt(s,"hellothere",str));
103*8190Smckusick 		fprintf(stderr,"\n");
104*8190Smckusick 		}
105*8190Smckusick 	}
106*8190Smckusick */
107*8190Smckusick /*
108*8190Smckusick 	To encrypt:
109*8190Smckusick 	The first level of call splits the input strings into strings
110*8190Smckusick 	no longer than 8 characters, for encryption.
111*8190Smckusick 	Then the encryption of 8 characters breaks all but the top bit
112*8190Smckusick 	of each character into a 64-character block, each character
113*8190Smckusick 	with 1 or 0 corresponding to binary.
114*8190Smckusick 	The key is set likewise.
115*8190Smckusick 	The encrypted form is then converted, 6 bits at a time,
116*8190Smckusick 	into an ASCII string.
117*8190Smckusick 
118*8190Smckusick 	To decrypt:
119*8190Smckusick 	We take the result of the encryption, 6 significant bits
120*8190Smckusick 	per character, and convert it to the block(64-char) fmt.
121*8190Smckusick 	This is decrypted by running the nbs algorithm in reverse,
122*8190Smckusick 	and transformed back into 7bit ASCII.
123*8190Smckusick 
124*8190Smckusick 	The subroutines to do ASCII blocking and deblocking
125*8190Smckusick 	are .....clr and the funny 6-bit code are .....not.
126*8190Smckusick 
127*8190Smckusick */
128*8190Smckusick 
nbs8encrypt(str,key)129*8190Smckusick char *nbs8encrypt(str,key)
130*8190Smckusick char *str, *key; {
131*8190Smckusick 	static char keyblk[100], blk[100];
132*8190Smckusick 	register int i;
133*8190Smckusick 
134*8190Smckusick 	enblkclr(keyblk,key);
135*8190Smckusick 	nbssetkey(keyblk);
136*8190Smckusick 
137*8190Smckusick 	for(i=0;i<48;i++) E[i] = e[i];
138*8190Smckusick 	enblkclr(blk,str);
139*8190Smckusick 	blkencrypt(blk,0);			/* forward dir */
140*8190Smckusick 
141*8190Smckusick 	return(deblknot(blk));
142*8190Smckusick }
nbs8decrypt(crp,key)143*8190Smckusick char *nbs8decrypt(crp,key)
144*8190Smckusick char *crp, *key; {
145*8190Smckusick 	static char keyblk[100], blk[100];
146*8190Smckusick 	register int i;
147*8190Smckusick 
148*8190Smckusick 	enblkclr(keyblk,key);
149*8190Smckusick 	nbssetkey(keyblk);
150*8190Smckusick 
151*8190Smckusick 	for(i=0;i<48;i++) E[i] = e[i];
152*8190Smckusick 	enblknot(blk,crp);
153*8190Smckusick 	blkencrypt(blk,1);			/* backward dir */
154*8190Smckusick 
155*8190Smckusick 	return(deblkclr(blk));
156*8190Smckusick }
enblkclr(blk,str)157*8190Smckusick enblkclr(blk,str)		/* ignores top bit of chars in string str */
158*8190Smckusick char *blk,*str; {
159*8190Smckusick 	register int i,j;
160*8190Smckusick 	char c;
161*8190Smckusick 	for(i=0;i<70;i++)blk[i] = 0;
162*8190Smckusick 	for(i=0; (c= *str) && i<64; str++){
163*8190Smckusick 		for(j=0; j<7; j++, i++)
164*8190Smckusick 			blk[i] = (c>>(6-j)) & 01;
165*8190Smckusick 		i++;
166*8190Smckusick 		}
167*8190Smckusick 	}
deblkclr(blk)168*8190Smckusick char *deblkclr(blk)
169*8190Smckusick char *blk; {
170*8190Smckusick 	register int i,j;
171*8190Smckusick 	char c;
172*8190Smckusick 	static char iobuf[30];
173*8190Smckusick 	for(i=0; i<10; i++){
174*8190Smckusick 		c = 0;
175*8190Smckusick 		for(j=0; j<7; j++){
176*8190Smckusick 			c <<= 1;
177*8190Smckusick 			c |= blk[8*i+j];
178*8190Smckusick 			}
179*8190Smckusick 		iobuf[i] = c;
180*8190Smckusick 	}
181*8190Smckusick 	iobuf[i] = 0;
182*8190Smckusick 	return(iobuf);
183*8190Smckusick 	}
enblknot(blk,crp)184*8190Smckusick enblknot(blk,crp)
185*8190Smckusick char *blk;
186*8190Smckusick char *crp; {
187*8190Smckusick 	register int i,j;
188*8190Smckusick 	char c;
189*8190Smckusick 	for(i=0;i<70;i++)blk[i] = 0;
190*8190Smckusick 	for(i=0; (c= *crp) && i<64; crp++){
191*8190Smckusick 		if(c>'Z') c -= 6;
192*8190Smckusick 		if(c>'9') c -= 7;
193*8190Smckusick 		c -= '.';
194*8190Smckusick 		for(j=0; j<6; j++, i++)
195*8190Smckusick 			blk[i] = (c>>(5-j)) & 01;
196*8190Smckusick 		}
197*8190Smckusick 	}
deblknot(blk)198*8190Smckusick char *deblknot(blk)
199*8190Smckusick char *blk; {
200*8190Smckusick 	register int i,j;
201*8190Smckusick 	char c;
202*8190Smckusick 	static char iobuf[30];
203*8190Smckusick 	for(i=0; i<11; i++){
204*8190Smckusick 		c = 0;
205*8190Smckusick 		for(j=0; j<6; j++){
206*8190Smckusick 			c <<= 1;
207*8190Smckusick 			c |= blk[6*i+j];
208*8190Smckusick 			}
209*8190Smckusick 		c += '.';
210*8190Smckusick 		if(c > '9')c += 7;
211*8190Smckusick 		if(c > 'Z')c += 6;
212*8190Smckusick 		iobuf[i] = c;
213*8190Smckusick 	}
214*8190Smckusick 	iobuf[i] = 0;
215*8190Smckusick 	return(iobuf);
216*8190Smckusick 	}
217*8190Smckusick /*
218*8190Smckusick  * This program implements the
219*8190Smckusick  * Proposed Federal Information Processing
220*8190Smckusick  *  Data Encryption Standard.
221*8190Smckusick  * See Federal Register, March 17, 1975 (40FR12134)
222*8190Smckusick  */
223*8190Smckusick 
224*8190Smckusick /*
225*8190Smckusick  * Initial permutation,
226*8190Smckusick  */
227*8190Smckusick static	char	IP[] = {
228*8190Smckusick 	58,50,42,34,26,18,10, 2,
229*8190Smckusick 	60,52,44,36,28,20,12, 4,
230*8190Smckusick 	62,54,46,38,30,22,14, 6,
231*8190Smckusick 	64,56,48,40,32,24,16, 8,
232*8190Smckusick 	57,49,41,33,25,17, 9, 1,
233*8190Smckusick 	59,51,43,35,27,19,11, 3,
234*8190Smckusick 	61,53,45,37,29,21,13, 5,
235*8190Smckusick 	63,55,47,39,31,23,15, 7,
236*8190Smckusick };
237*8190Smckusick 
238*8190Smckusick /*
239*8190Smckusick  * Final permutation, FP = IP^(-1)
240*8190Smckusick  */
241*8190Smckusick static	char	FP[] = {
242*8190Smckusick 	40, 8,48,16,56,24,64,32,
243*8190Smckusick 	39, 7,47,15,55,23,63,31,
244*8190Smckusick 	38, 6,46,14,54,22,62,30,
245*8190Smckusick 	37, 5,45,13,53,21,61,29,
246*8190Smckusick 	36, 4,44,12,52,20,60,28,
247*8190Smckusick 	35, 3,43,11,51,19,59,27,
248*8190Smckusick 	34, 2,42,10,50,18,58,26,
249*8190Smckusick 	33, 1,41, 9,49,17,57,25,
250*8190Smckusick };
251*8190Smckusick 
252*8190Smckusick /*
253*8190Smckusick  * Permuted-choice 1 from the key bits
254*8190Smckusick  * to yield C and D.
255*8190Smckusick  * Note that bits 8,16... are left out:
256*8190Smckusick  * They are intended for a parity check.
257*8190Smckusick  */
258*8190Smckusick static	char	PC1_C[] = {
259*8190Smckusick 	57,49,41,33,25,17, 9,
260*8190Smckusick 	 1,58,50,42,34,26,18,
261*8190Smckusick 	10, 2,59,51,43,35,27,
262*8190Smckusick 	19,11, 3,60,52,44,36,
263*8190Smckusick };
264*8190Smckusick 
265*8190Smckusick static	char	PC1_D[] = {
266*8190Smckusick 	63,55,47,39,31,23,15,
267*8190Smckusick 	 7,62,54,46,38,30,22,
268*8190Smckusick 	14, 6,61,53,45,37,29,
269*8190Smckusick 	21,13, 5,28,20,12, 4,
270*8190Smckusick };
271*8190Smckusick 
272*8190Smckusick /*
273*8190Smckusick  * Sequence of shifts used for the key schedule.
274*8190Smckusick */
275*8190Smckusick static	char	shifts[] = {
276*8190Smckusick 	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
277*8190Smckusick };
278*8190Smckusick 
279*8190Smckusick /*
280*8190Smckusick  * Permuted-choice 2, to pick out the bits from
281*8190Smckusick  * the CD array that generate the key schedule.
282*8190Smckusick  */
283*8190Smckusick static	char	PC2_C[] = {
284*8190Smckusick 	14,17,11,24, 1, 5,
285*8190Smckusick 	 3,28,15, 6,21,10,
286*8190Smckusick 	23,19,12, 4,26, 8,
287*8190Smckusick 	16, 7,27,20,13, 2,
288*8190Smckusick };
289*8190Smckusick 
290*8190Smckusick static	char	PC2_D[] = {
291*8190Smckusick 	41,52,31,37,47,55,
292*8190Smckusick 	30,40,51,45,33,48,
293*8190Smckusick 	44,49,39,56,34,53,
294*8190Smckusick 	46,42,50,36,29,32,
295*8190Smckusick };
296*8190Smckusick 
297*8190Smckusick /*
298*8190Smckusick  * The C and D arrays used to calculate the key schedule.
299*8190Smckusick  */
300*8190Smckusick 
301*8190Smckusick static	char	C[28];
302*8190Smckusick static	char	D[28];
303*8190Smckusick /*
304*8190Smckusick  * The key schedule.
305*8190Smckusick  * Generated from the key.
306*8190Smckusick  */
307*8190Smckusick static	char	KS[16][48];
308*8190Smckusick 
309*8190Smckusick /*
310*8190Smckusick  * Set up the key schedule from the key.
311*8190Smckusick  */
312*8190Smckusick 
nbssetkey(key)313*8190Smckusick nbssetkey(key)
314*8190Smckusick char *key;
315*8190Smckusick {
316*8190Smckusick 	register i, j, k;
317*8190Smckusick 	int t;
318*8190Smckusick 
319*8190Smckusick 	/*
320*8190Smckusick 	 * First, generate C and D by permuting
321*8190Smckusick 	 * the key.  The low order bit of each
322*8190Smckusick 	 * 8-bit char is not used, so C and D are only 28
323*8190Smckusick 	 * bits apiece.
324*8190Smckusick 	 */
325*8190Smckusick 	for (i=0; i<28; i++) {
326*8190Smckusick 		C[i] = key[PC1_C[i]-1];
327*8190Smckusick 		D[i] = key[PC1_D[i]-1];
328*8190Smckusick 	}
329*8190Smckusick 	/*
330*8190Smckusick 	 * To generate Ki, rotate C and D according
331*8190Smckusick 	 * to schedule and pick up a permutation
332*8190Smckusick 	 * using PC2.
333*8190Smckusick 	 */
334*8190Smckusick 	for (i=0; i<16; i++) {
335*8190Smckusick 		/*
336*8190Smckusick 		 * rotate.
337*8190Smckusick 		 */
338*8190Smckusick 		for (k=0; k<shifts[i]; k++) {
339*8190Smckusick 			t = C[0];
340*8190Smckusick 			for (j=0; j<28-1; j++)
341*8190Smckusick 				C[j] = C[j+1];
342*8190Smckusick 			C[27] = t;
343*8190Smckusick 			t = D[0];
344*8190Smckusick 			for (j=0; j<28-1; j++)
345*8190Smckusick 				D[j] = D[j+1];
346*8190Smckusick 			D[27] = t;
347*8190Smckusick 		}
348*8190Smckusick 		/*
349*8190Smckusick 		 * get Ki. Note C and D are concatenated.
350*8190Smckusick 		 */
351*8190Smckusick 		for (j=0; j<24; j++) {
352*8190Smckusick 			KS[i][j] = C[PC2_C[j]-1];
353*8190Smckusick 			KS[i][j+24] = D[PC2_D[j]-28-1];
354*8190Smckusick 		}
355*8190Smckusick 	}
356*8190Smckusick }
357*8190Smckusick 
358*8190Smckusick /*
359*8190Smckusick  * The E bit-selection table.
360*8190Smckusick  */
361*8190Smckusick static char	e[] = {
362*8190Smckusick 	32, 1, 2, 3, 4, 5,
363*8190Smckusick 	 4, 5, 6, 7, 8, 9,
364*8190Smckusick 	 8, 9,10,11,12,13,
365*8190Smckusick 	12,13,14,15,16,17,
366*8190Smckusick 	16,17,18,19,20,21,
367*8190Smckusick 	20,21,22,23,24,25,
368*8190Smckusick 	24,25,26,27,28,29,
369*8190Smckusick 	28,29,30,31,32, 1,
370*8190Smckusick };
371*8190Smckusick 
372*8190Smckusick /*
373*8190Smckusick  * The 8 selection functions.
374*8190Smckusick  * For some reason, they give a 0-origin
375*8190Smckusick  * index, unlike everything else.
376*8190Smckusick  */
377*8190Smckusick static	char	S[8][64] = {
378*8190Smckusick 	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
379*8190Smckusick 	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
380*8190Smckusick 	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
381*8190Smckusick 	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
382*8190Smckusick 
383*8190Smckusick 	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
384*8190Smckusick 	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
385*8190Smckusick 	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
386*8190Smckusick 	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
387*8190Smckusick 
388*8190Smckusick 	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
389*8190Smckusick 	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
390*8190Smckusick 	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
391*8190Smckusick 	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
392*8190Smckusick 
393*8190Smckusick 	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
394*8190Smckusick 	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
395*8190Smckusick 	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
396*8190Smckusick 	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
397*8190Smckusick 
398*8190Smckusick 	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
399*8190Smckusick 	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
400*8190Smckusick 	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
401*8190Smckusick 	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
402*8190Smckusick 
403*8190Smckusick 	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
404*8190Smckusick 	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
405*8190Smckusick 	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
406*8190Smckusick 	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
407*8190Smckusick 
408*8190Smckusick 	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
409*8190Smckusick 	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
410*8190Smckusick 	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
411*8190Smckusick 	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
412*8190Smckusick 
413*8190Smckusick 	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
414*8190Smckusick 	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
415*8190Smckusick 	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
416*8190Smckusick 	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
417*8190Smckusick };
418*8190Smckusick 
419*8190Smckusick /*
420*8190Smckusick  * P is a permutation on the selected combination
421*8190Smckusick  * of the current L and key.
422*8190Smckusick  */
423*8190Smckusick static	char	P[] = {
424*8190Smckusick 	16, 7,20,21,
425*8190Smckusick 	29,12,28,17,
426*8190Smckusick 	 1,15,23,26,
427*8190Smckusick 	 5,18,31,10,
428*8190Smckusick 	 2, 8,24,14,
429*8190Smckusick 	32,27, 3, 9,
430*8190Smckusick 	19,13,30, 6,
431*8190Smckusick 	22,11, 4,25,
432*8190Smckusick };
433*8190Smckusick 
434*8190Smckusick /*
435*8190Smckusick  * The current block, divided into 2 halves.
436*8190Smckusick  */
437*8190Smckusick static	char	L[32], R[32];
438*8190Smckusick static	char	tempL[32];
439*8190Smckusick static	char	f[32];
440*8190Smckusick 
441*8190Smckusick /*
442*8190Smckusick  * The combination of the key and the input, before selection.
443*8190Smckusick  */
444*8190Smckusick static	char	preS[48];
445*8190Smckusick 
446*8190Smckusick /*
447*8190Smckusick  * The payoff: encrypt a block.
448*8190Smckusick  */
449*8190Smckusick 
blkencrypt(block,edflag)450*8190Smckusick blkencrypt(block, edflag)
451*8190Smckusick char *block;
452*8190Smckusick {
453*8190Smckusick 	int i, ii;
454*8190Smckusick 	register t, j, k;
455*8190Smckusick 
456*8190Smckusick 	/*
457*8190Smckusick 	 * First, permute the bits in the input
458*8190Smckusick 	 */
459*8190Smckusick 	for (j=0; j<64; j++)
460*8190Smckusick 		L[j] = block[IP[j]-1];
461*8190Smckusick 	/*
462*8190Smckusick 	 * Perform an encryption operation 16 times.
463*8190Smckusick 	 */
464*8190Smckusick 	for (ii=0; ii<16; ii++) {
465*8190Smckusick 		/*
466*8190Smckusick 		 * Set direction
467*8190Smckusick 		 */
468*8190Smckusick 		if (edflag)
469*8190Smckusick 			i = 15-ii;
470*8190Smckusick 		else
471*8190Smckusick 			i = ii;
472*8190Smckusick 		/*
473*8190Smckusick 		 * Save the R array,
474*8190Smckusick 		 * which will be the new L.
475*8190Smckusick 		 */
476*8190Smckusick 		for (j=0; j<32; j++)
477*8190Smckusick 			tempL[j] = R[j];
478*8190Smckusick 		/*
479*8190Smckusick 		 * Expand R to 48 bits using the E selector;
480*8190Smckusick 		 * exclusive-or with the current key bits.
481*8190Smckusick 		 */
482*8190Smckusick 		for (j=0; j<48; j++)
483*8190Smckusick 			preS[j] = R[E[j]-1] ^ KS[i][j];
484*8190Smckusick 		/*
485*8190Smckusick 		 * The pre-select bits are now considered
486*8190Smckusick 		 * in 8 groups of 6 bits each.
487*8190Smckusick 		 * The 8 selection functions map these
488*8190Smckusick 		 * 6-bit quantities into 4-bit quantities
489*8190Smckusick 		 * and the results permuted
490*8190Smckusick 		 * to make an f(R, K).
491*8190Smckusick 		 * The indexing into the selection functions
492*8190Smckusick 		 * is peculiar; it could be simplified by
493*8190Smckusick 		 * rewriting the tables.
494*8190Smckusick 		 */
495*8190Smckusick 		for (j=0; j<8; j++) {
496*8190Smckusick 			t = 6*j;
497*8190Smckusick 			k = S[j][(preS[t+0]<<5)+
498*8190Smckusick 				(preS[t+1]<<3)+
499*8190Smckusick 				(preS[t+2]<<2)+
500*8190Smckusick 				(preS[t+3]<<1)+
501*8190Smckusick 				(preS[t+4]<<0)+
502*8190Smckusick 				(preS[t+5]<<4)];
503*8190Smckusick 			t = 4*j;
504*8190Smckusick 			f[t+0] = (k>>3)&01;
505*8190Smckusick 			f[t+1] = (k>>2)&01;
506*8190Smckusick 			f[t+2] = (k>>1)&01;
507*8190Smckusick 			f[t+3] = (k>>0)&01;
508*8190Smckusick 		}
509*8190Smckusick 		/*
510*8190Smckusick 		 * The new R is L ^ f(R, K).
511*8190Smckusick 		 * The f here has to be permuted first, though.
512*8190Smckusick 		 */
513*8190Smckusick 		for (j=0; j<32; j++)
514*8190Smckusick 			R[j] = L[j] ^ f[P[j]-1];
515*8190Smckusick 		/*
516*8190Smckusick 		 * Finally, the new L (the original R)
517*8190Smckusick 		 * is copied back.
518*8190Smckusick 		 */
519*8190Smckusick 		for (j=0; j<32; j++)
520*8190Smckusick 			L[j] = tempL[j];
521*8190Smckusick 	}
522*8190Smckusick 	/*
523*8190Smckusick 	 * The output L and R are reversed.
524*8190Smckusick 	 */
525*8190Smckusick 	for (j=0; j<32; j++) {
526*8190Smckusick 		t = L[j];
527*8190Smckusick 		L[j] = R[j];
528*8190Smckusick 		R[j] = t;
529*8190Smckusick 	}
530*8190Smckusick 	/*
531*8190Smckusick 	 * The final output
532*8190Smckusick 	 * gets the inverse permutation of the very original.
533*8190Smckusick 	 */
534*8190Smckusick 	for (j=0; j<64; j++)
535*8190Smckusick 		block[j] = L[FP[j]-1];
536*8190Smckusick }
537