xref: /netbsd-src/lib/libtelnet/enc_des.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /*	$NetBSD: enc_des.c,v 1.6 2001/11/30 04:44:24 lukem Exp $	*/
2 
3 /*-
4  * Copyright (c) 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)enc_des.c	8.3 (Berkeley) 5/30/95"; */
40 #else
41 __RCSID("$NetBSD: enc_des.c,v 1.6 2001/11/30 04:44:24 lukem Exp $");
42 #endif
43 #endif /* not lint */
44 
45 #ifdef	ENCRYPTION
46 # ifdef	AUTHENTICATION
47 #  ifdef DES_ENCRYPTION
48 #include <arpa/telnet.h>
49 #include <stdio.h>
50 #include <string.h>
51 #ifdef	__STDC__
52 #include <stdlib.h>
53 #endif
54 
55 #include <des.h>
56 #include "encrypt.h"
57 #include "key-proto.h"
58 #include "misc-proto.h"
59 
60 #include <sys/cdefs.h>
61 #define P __P
62 
63 #define	CFB	0
64 #define	OFB	1
65 
66 #define	NO_SEND_IV	1
67 #define	NO_RECV_IV	2
68 #define	NO_KEYID	4
69 #define	IN_PROGRESS	(NO_SEND_IV|NO_RECV_IV|NO_KEYID)
70 #define	SUCCESS		0
71 #define	FAILED		-1
72 
73 
74 struct fb {
75 	Block krbdes_key;
76 	Schedule krbdes_sched;
77 	Block temp_feed;
78 	unsigned char fb_feed[64];
79 	int need_start;
80 	int state[2];
81 	int keyid[2];
82 	int once;
83 	struct stinfo {
84 		Block		str_output;
85 		Block		str_feed;
86 		Block		str_iv;
87 		Block		str_ikey;
88 		Schedule	str_sched;
89 		int		str_index;
90 		int		str_flagshift;
91 	} streams[2];
92 };
93 
94 static struct fb fb[2];
95 
96 struct keyidlist {
97 	char	*keyid;
98 	int	keyidlen;
99 	char	*key;
100 	int	keylen;
101 	int	flags;
102 } keyidlist [] = {
103 	{ "\0", 1, 0, 0, 0 },		/* default key of zero */
104 	{ 0, 0, 0, 0, 0 }
105 };
106 
107 #define	KEYFLAG_MASK	03
108 
109 #define	KEYFLAG_NOINIT	00
110 #define	KEYFLAG_INIT	01
111 #define	KEYFLAG_OK	02
112 #define	KEYFLAG_BAD	03
113 
114 #define	KEYFLAG_SHIFT	2
115 
116 #define	SHIFT_VAL(a,b)	(KEYFLAG_SHIFT*((a)+((b)*2)))
117 
118 #define	FB64_IV		1
119 #define	FB64_IV_OK	2
120 #define	FB64_IV_BAD	3
121 
122 
123 void fb64_stream_iv P((Block, struct stinfo *));
124 void fb64_init P((struct fb *));
125 static int fb64_start P((struct fb *, int, int));
126 int fb64_is P((unsigned char *, int, struct fb *));
127 int fb64_reply P((unsigned char *, int, struct fb *));
128 static void fb64_session P((Session_Key *, int, struct fb *));
129 void fb64_stream_key P((Block *, struct stinfo *));
130 int fb64_keyid P((int, unsigned char *, int *, struct fb *));
131 
132 	void
133 cfb64_init(server)
134 	int server;
135 {
136 	fb64_init(&fb[CFB]);
137 	fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64;
138 	fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
139 	fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
140 }
141 
142 	void
143 ofb64_init(server)
144 	int server;
145 {
146 	fb64_init(&fb[OFB]);
147 	fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64;
148 	fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
149 	fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
150 }
151 
152 	void
153 fb64_init(fbp)
154 	register struct fb *fbp;
155 {
156 	memset((void *)fbp, 0, sizeof(*fbp));
157 	fbp->state[0] = fbp->state[1] = FAILED;
158 	fbp->fb_feed[0] = IAC;
159 	fbp->fb_feed[1] = SB;
160 	fbp->fb_feed[2] = TELOPT_ENCRYPT;
161 	fbp->fb_feed[3] = ENCRYPT_IS;
162 }
163 
164 /*
165  * Returns:
166  *	-1: some error.  Negotiation is done, encryption not ready.
167  *	 0: Successful, initial negotiation all done.
168  *	 1: successful, negotiation not done yet.
169  *	 2: Not yet.  Other things (like getting the key from
170  *	    Kerberos) have to happen before we can continue.
171  */
172 	int
173 cfb64_start(dir, server)
174 	int dir;
175 	int server;
176 {
177 	return(fb64_start(&fb[CFB], dir, server));
178 }
179 	int
180 ofb64_start(dir, server)
181 	int dir;
182 	int server;
183 {
184 	return(fb64_start(&fb[OFB], dir, server));
185 }
186 
187 	static int
188 fb64_start(fbp, dir, server)
189 	struct fb *fbp;
190 	int dir;
191 	int server;
192 {
193 	int x;
194 	unsigned char *p;
195 	register int state;
196 
197 	switch (dir) {
198 	case DIR_DECRYPT:
199 		/*
200 		 * This is simply a request to have the other side
201 		 * start output (our input).  He will negotiate an
202 		 * IV so we need not look for it.
203 		 */
204 		state = fbp->state[dir-1];
205 		if (state == FAILED)
206 			state = IN_PROGRESS;
207 		break;
208 
209 	case DIR_ENCRYPT:
210 		state = fbp->state[dir-1];
211 		if (state == FAILED)
212 			state = IN_PROGRESS;
213 		else if ((state & NO_SEND_IV) == 0)
214 			break;
215 
216 		if (!VALIDKEY(fbp->krbdes_key)) {
217 			fbp->need_start = 1;
218 			break;
219 		}
220 		state &= ~NO_SEND_IV;
221 		state |= NO_RECV_IV;
222 		if (encrypt_debug_mode)
223 			printf("Creating new feed\r\n");
224 		/*
225 		 * Create a random feed and send it over.
226 		 */
227 		des_new_random_key(&fbp->temp_feed);
228 		des_ecb_encrypt(&fbp->temp_feed, &fbp->temp_feed,
229 				fbp->krbdes_sched, 1);
230 		p = fbp->fb_feed + 3;
231 		*p++ = ENCRYPT_IS;
232 		p++;
233 		*p++ = FB64_IV;
234 		for (x = 0; x < sizeof(Block); ++x) {
235 			if ((*p++ = fbp->temp_feed[x]) == IAC)
236 				*p++ = IAC;
237 		}
238 		*p++ = IAC;
239 		*p++ = SE;
240 		printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
241 		telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
242 		break;
243 	default:
244 		return(FAILED);
245 	}
246 	return(fbp->state[dir-1] = state);
247 }
248 
249 /*
250  * Returns:
251  *	-1: some error.  Negotiation is done, encryption not ready.
252  *	 0: Successful, initial negotiation all done.
253  *	 1: successful, negotiation not done yet.
254  */
255 	int
256 cfb64_is(data, cnt)
257 	unsigned char *data;
258 	int cnt;
259 {
260 	return(fb64_is(data, cnt, &fb[CFB]));
261 }
262 	int
263 ofb64_is(data, cnt)
264 	unsigned char *data;
265 	int cnt;
266 {
267 	return(fb64_is(data, cnt, &fb[OFB]));
268 }
269 
270 	int
271 fb64_is(data, cnt, fbp)
272 	unsigned char *data;
273 	int cnt;
274 	struct fb *fbp;
275 {
276 	unsigned char *p;
277 	register int state = fbp->state[DIR_DECRYPT-1];
278 
279 	if (cnt-- < 1)
280 		goto failure;
281 
282 	switch (*data++) {
283 	case FB64_IV:
284 		if (cnt != sizeof(Block)) {
285 			if (encrypt_debug_mode)
286 				printf("CFB64: initial vector failed on size\r\n");
287 			state = FAILED;
288 			goto failure;
289 		}
290 
291 		if (encrypt_debug_mode)
292 			printf("CFB64: initial vector received\r\n");
293 
294 		if (encrypt_debug_mode)
295 			printf("Initializing Decrypt stream\r\n");
296 
297 		fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
298 
299 		p = fbp->fb_feed + 3;
300 		*p++ = ENCRYPT_REPLY;
301 		p++;
302 		*p++ = FB64_IV_OK;
303 		*p++ = IAC;
304 		*p++ = SE;
305 		printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
306 		telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
307 
308 		state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS;
309 		break;
310 
311 	default:
312 		if (encrypt_debug_mode) {
313 			printf("Unknown option type: %d\r\n", *(data-1));
314 			printd(data, cnt);
315 			printf("\r\n");
316 		}
317 		/* FALL THROUGH */
318 	failure:
319 		/*
320 		 * We failed.  Send an FB64_IV_BAD option
321 		 * to the other side so it will know that
322 		 * things failed.
323 		 */
324 		p = fbp->fb_feed + 3;
325 		*p++ = ENCRYPT_REPLY;
326 		p++;
327 		*p++ = FB64_IV_BAD;
328 		*p++ = IAC;
329 		*p++ = SE;
330 		printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]);
331 		telnet_net_write(fbp->fb_feed, p - fbp->fb_feed);
332 
333 		break;
334 	}
335 	return(fbp->state[DIR_DECRYPT-1] = state);
336 }
337 
338 /*
339  * Returns:
340  *	-1: some error.  Negotiation is done, encryption not ready.
341  *	 0: Successful, initial negotiation all done.
342  *	 1: successful, negotiation not done yet.
343  */
344 	int
345 cfb64_reply(data, cnt)
346 	unsigned char *data;
347 	int cnt;
348 {
349 	return(fb64_reply(data, cnt, &fb[CFB]));
350 }
351 	int
352 ofb64_reply(data, cnt)
353 	unsigned char *data;
354 	int cnt;
355 {
356 	return(fb64_reply(data, cnt, &fb[OFB]));
357 }
358 
359 
360 	int
361 fb64_reply(data, cnt, fbp)
362 	unsigned char *data;
363 	int cnt;
364 	struct fb *fbp;
365 {
366 	register int state = fbp->state[DIR_ENCRYPT-1];
367 
368 	if (cnt-- < 1)
369 		goto failure;
370 
371 	switch (*data++) {
372 	case FB64_IV_OK:
373 		fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
374 		if (state == FAILED)
375 			state = IN_PROGRESS;
376 		state &= ~NO_RECV_IV;
377 		encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
378 		break;
379 
380 	case FB64_IV_BAD:
381 		memset(fbp->temp_feed, 0, sizeof(Block));
382 		fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
383 		state = FAILED;
384 		break;
385 
386 	default:
387 		if (encrypt_debug_mode) {
388 			printf("Unknown option type: %d\r\n", data[-1]);
389 			printd(data, cnt);
390 			printf("\r\n");
391 		}
392 		/* FALL THROUGH */
393 	failure:
394 		state = FAILED;
395 		break;
396 	}
397 	return(fbp->state[DIR_ENCRYPT-1] = state);
398 }
399 
400 	void
401 cfb64_session(key, server)
402 	Session_Key *key;
403 	int server;
404 {
405 	fb64_session(key, server, &fb[CFB]);
406 }
407 
408 	void
409 ofb64_session(key, server)
410 	Session_Key *key;
411 	int server;
412 {
413 	fb64_session(key, server, &fb[OFB]);
414 }
415 
416 	static void
417 fb64_session(key, server, fbp)
418 	Session_Key *key;
419 	int server;
420 	struct fb *fbp;
421 {
422 
423 	if (!key || key->type != SK_DES) {
424 		if (encrypt_debug_mode)
425 			printf("Can't set krbdes's session key (%d != %d)\r\n",
426 				key ? key->type : -1, SK_DES);
427 		return;
428 	}
429 	memmove((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
430 
431 	fb64_stream_key(&fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]);
432 	fb64_stream_key(&fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]);
433 
434 	if (fbp->once == 0) {
435 		des_init_random_number_generator(&fbp->krbdes_key);
436 		fbp->once = 1;
437 	}
438 	des_key_sched(&fbp->krbdes_key, fbp->krbdes_sched);
439 	/*
440 	 * Now look to see if krbdes_start() was was waiting for
441 	 * the key to show up.  If so, go ahead an call it now
442 	 * that we have the key.
443 	 */
444 	if (fbp->need_start) {
445 		fbp->need_start = 0;
446 		fb64_start(fbp, DIR_ENCRYPT, server);
447 	}
448 }
449 
450 /*
451  * We only accept a keyid of 0.  If we get a keyid of
452  * 0, then mark the state as SUCCESS.
453  */
454 	int
455 cfb64_keyid(dir, kp, lenp)
456 	int dir, *lenp;
457 	unsigned char *kp;
458 {
459 	return(fb64_keyid(dir, kp, lenp, &fb[CFB]));
460 }
461 
462 	int
463 ofb64_keyid(dir, kp, lenp)
464 	int dir, *lenp;
465 	unsigned char *kp;
466 {
467 	return(fb64_keyid(dir, kp, lenp, &fb[OFB]));
468 }
469 
470 	int
471 fb64_keyid(dir, kp, lenp, fbp)
472 	int dir, *lenp;
473 	unsigned char *kp;
474 	struct fb *fbp;
475 {
476 	register int state = fbp->state[dir-1];
477 
478 	if (*lenp != 1 || (*kp != '\0')) {
479 		*lenp = 0;
480 		return(state);
481 	}
482 
483 	if (state == FAILED)
484 		state = IN_PROGRESS;
485 
486 	state &= ~NO_KEYID;
487 
488 	return(fbp->state[dir-1] = state);
489 }
490 
491 	void
492 fb64_printsub(data, cnt, buf, buflen, type)
493 	unsigned char *data, *buf, *type;
494 	int cnt, buflen;
495 {
496 	char lbuf[32];
497 	register int i;
498 	char *cp;
499 
500 	buf[buflen-1] = '\0';		/* make sure it's NULL terminated */
501 	buflen -= 1;
502 
503 	switch(data[2]) {
504 	case FB64_IV:
505 		sprintf(lbuf, "%s_IV", type);
506 		cp = lbuf;
507 		goto common;
508 
509 	case FB64_IV_OK:
510 		sprintf(lbuf, "%s_IV_OK", type);
511 		cp = lbuf;
512 		goto common;
513 
514 	case FB64_IV_BAD:
515 		sprintf(lbuf, "%s_IV_BAD", type);
516 		cp = lbuf;
517 		goto common;
518 
519 	default:
520 		sprintf(lbuf, " %d (unknown)", data[2]);
521 		cp = lbuf;
522 	common:
523 		for (; (buflen > 0) && (*buf = *cp++); buf++)
524 			buflen--;
525 		for (i = 3; i < cnt; i++) {
526 			sprintf(lbuf, " %d", data[i]);
527 			for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
528 				buflen--;
529 		}
530 		break;
531 	}
532 }
533 
534 	void
535 cfb64_printsub(data, cnt, buf, buflen)
536 	unsigned char *data, *buf;
537 	int cnt, buflen;
538 {
539 	fb64_printsub(data, cnt, buf, buflen, "CFB64");
540 }
541 
542 	void
543 ofb64_printsub(data, cnt, buf, buflen)
544 	unsigned char *data, *buf;
545 	int cnt, buflen;
546 {
547 	fb64_printsub(data, cnt, buf, buflen, "OFB64");
548 }
549 
550 	void
551 fb64_stream_iv(seed, stp)
552 	Block seed;
553 	register struct stinfo *stp;
554 {
555 
556 	memmove((void *)stp->str_iv, (void *)seed, sizeof(Block));
557 	memmove((void *)stp->str_output, (void *)seed, sizeof(Block));
558 
559 	des_key_sched(&stp->str_ikey, stp->str_sched);
560 
561 	stp->str_index = sizeof(Block);
562 }
563 
564 	void
565 fb64_stream_key(key, stp)
566 	Block *key;
567 	register struct stinfo *stp;
568 {
569 	memmove((void *)stp->str_ikey, (void *)key, sizeof(Block));
570 	des_key_sched(key, stp->str_sched);
571 
572 	memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block));
573 
574 	stp->str_index = sizeof(Block);
575 }
576 
577 /*
578  * DES 64 bit Cipher Feedback
579  *
580  *     key --->+-----+
581  *          +->| DES |--+
582  *          |  +-----+  |
583  *	    |           v
584  *  INPUT --(--------->(+)+---> DATA
585  *          |             |
586  *	    +-------------+
587  *
588  *
589  * Given:
590  *	iV: Initial vector, 64 bits (8 bytes) long.
591  *	Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
592  *	On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
593  *
594  *	V0 = DES(iV, key)
595  *	On = Dn ^ Vn
596  *	V(n+1) = DES(On, key)
597  */
598 
599 	void
600 cfb64_encrypt(s, c)
601 	register unsigned char *s;
602 	int c;
603 {
604 	register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1];
605 	register int idx;
606 
607 	idx = stp->str_index;
608 	while (c-- > 0) {
609 		if (idx == sizeof(Block)) {
610 			Block b;
611 			des_ecb_encrypt(&stp->str_output, &b, stp->str_sched, 1);
612 			memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
613 			idx = 0;
614 		}
615 
616 		/* On encryption, we store (feed ^ data) which is cypher */
617 		*s = stp->str_output[idx] = (stp->str_feed[idx] ^ *s);
618 		s++;
619 		idx++;
620 	}
621 	stp->str_index = idx;
622 }
623 
624 	int
625 cfb64_decrypt(data)
626 	int data;
627 {
628 	register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1];
629 	int idx;
630 
631 	if (data == -1) {
632 		/*
633 		 * Back up one byte.  It is assumed that we will
634 		 * never back up more than one byte.  If we do, this
635 		 * may or may not work.
636 		 */
637 		if (stp->str_index)
638 			--stp->str_index;
639 		return(0);
640 	}
641 
642 	idx = stp->str_index++;
643 	if (idx == sizeof(Block)) {
644 		Block b;
645 		des_ecb_encrypt(&stp->str_output, &b, stp->str_sched, 1);
646 		memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
647 		stp->str_index = 1;	/* Next time will be 1 */
648 		idx = 0;		/* But now use 0 */
649 	}
650 
651 	/* On decryption we store (data) which is cypher. */
652 	stp->str_output[idx] = data;
653 	return(data ^ stp->str_feed[idx]);
654 }
655 
656 /*
657  * DES 64 bit Output Feedback
658  *
659  * key --->+-----+
660  *	+->| DES |--+
661  *	|  +-----+  |
662  *	+-----------+
663  *	            v
664  *  INPUT -------->(+) ----> DATA
665  *
666  * Given:
667  *	iV: Initial vector, 64 bits (8 bytes) long.
668  *	Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
669  *	On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
670  *
671  *	V0 = DES(iV, key)
672  *	V(n+1) = DES(Vn, key)
673  *	On = Dn ^ Vn
674  */
675 	void
676 ofb64_encrypt(s, c)
677 	register unsigned char *s;
678 	int c;
679 {
680 	register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1];
681 	register int idx;
682 
683 	idx = stp->str_index;
684 	while (c-- > 0) {
685 		if (idx == sizeof(Block)) {
686 			Block b;
687 			des_ecb_encrypt(&stp->str_feed, &b, stp->str_sched, 1);
688 			memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
689 			idx = 0;
690 		}
691 		*s++ ^= stp->str_feed[idx];
692 		idx++;
693 	}
694 	stp->str_index = idx;
695 }
696 
697 	int
698 ofb64_decrypt(data)
699 	int data;
700 {
701 	register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1];
702 	int idx;
703 
704 	if (data == -1) {
705 		/*
706 		 * Back up one byte.  It is assumed that we will
707 		 * never back up more than one byte.  If we do, this
708 		 * may or may not work.
709 		 */
710 		if (stp->str_index)
711 			--stp->str_index;
712 		return(0);
713 	}
714 
715 	idx = stp->str_index++;
716 	if (idx == sizeof(Block)) {
717 		Block b;
718 		des_ecb_encrypt(&stp->str_feed, &b, stp->str_sched, 1);
719 		memmove((void *)stp->str_feed, (void *)b, sizeof(Block));
720 		stp->str_index = 1;	/* Next time will be 1 */
721 		idx = 0;		/* But now use 0 */
722 	}
723 
724 	return(data ^ stp->str_feed[idx]);
725 }
726 #  endif /* DES_ENCRYPTION */
727 # endif	/* AUTHENTICATION */
728 #endif	/* ENCRYPTION */
729