source: trunk/third/kermit/ck_crp.c @ 20081

Revision 20081, 161.4 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20080, which included commits to RCS files with non-trunk default branches.
Line 
1char *ckcrpv = "Encryption Engine, 8.0.112, 21 Feb 2003";
2/*
3  C K _ C R P . C  -  Cryptography for C-Kermit"
4
5  Copyright (C) 1998, 2003,
6    Trustees of Columbia University in the City of New York.
7    All rights reserved.  See the C-Kermit COPYING.TXT file or the
8    copyright text in the ckcmai.c module for disclaimer and permissions.
9
10  Author:
11  Jeffrey E Altman (jaltman@columbia.edu).
12*/
13
14#define CK_CRP_C
15#ifdef CK_DES
16#ifdef CK_SSL
17#ifndef LIBDES
18#define LIBDES
19#endif /* LIBDES */
20#endif /* CK_SSL */
21#endif /* CK_DES */
22
23#ifdef CRYPT_DLL
24#define CK_AUTHENTICATION
25#define CK_ENCRYPTION
26#define CK_DES
27#define CK_CAST
28#ifndef LIBDES
29#define LIBDES
30#endif /* LIBDES */
31
32#define TELCMDS                         /* to define name array */
33#define TELOPTS                         /* to define name array */
34#define ENCRYPT_NAMES
35#endif /* CRYPT_DLL */
36
37#include "ckcsym.h"
38#include "ckcdeb.h"
39#include "ckcnet.h"
40
41#ifdef DEBUG
42#undef DEBUG
43#endif /* DEBUG */
44
45#ifdef CK_AUTHENTICATION
46#ifdef CK_ENCRYPTION
47#define ENCRYPTION
48#ifdef CK_DES
49#define DES_ENCRYPTION
50#endif /* CK_DES */
51#ifdef  CK_CAST
52#define CAST_ENCRYPTION
53#endif /* CK_CAST */
54#ifdef COMMENT
55#define CAST_EXPORT_ENCRYPTION
56#endif /* COMMENT */
57#endif /* CK_ENCRYPTION */
58#endif /* CK_AUTHENTICATION */
59
60#ifdef CK_ENCRYPTION
61
62#include "ckucmd.h"                     /* For struct keytab definition */
63#include "ckuath.h"
64#include "ckuat2.h"
65#ifdef MIT_CURRENT
66#include <krb5.h>
67#endif /* MIT_CURRENT */
68
69#include <stdlib.h>
70#include <string.h>
71#ifdef OS2
72#include <stdarg.h>
73#ifdef OS2ONLY
74#include <os2.h>
75#endif /* OS2ONLY */
76#include "ckosyn.h"
77#else /* OS2 */
78static char * tmpstring = NULL;
79#endif /* OS2 */
80
81#ifndef CAST_OR_EXPORT
82#ifdef CAST_ENCRYPTION
83#define CAST_OR_EXPORT
84#endif /* CAST_ENCRYPTION */
85#ifdef CAST_EXPORT_ENCRYPTION
86#define CAST_OR_EXPORT
87#endif /* CAST_EXPORT_ENCRYPTION */
88#endif /* CAST_OR_EXPORT */
89
90#ifdef CRYPT_DLL
91int cmd_quoting = 0;
92
93#ifndef TELOPT_MACRO
94int
95telopt_index(opt) int opt; {
96    if ( opt >= 0 && opt <= TELOPT_SEND_URL )
97        return(opt);
98    else if ( opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT )
99        return(opt-89);
100    else
101        return(NTELOPTS);
102}
103
104int
105telopt_ok(opt) int opt; {
106    return((opt >= TELOPT_BINARY && opt <= TELOPT_SEND_URL) ||
107        (opt >= TELOPT_PRAGMA_LOGON && opt <= TELOPT_PRAGMA_HEARTBEAT));
108}
109
110CHAR *
111telopt(opt) int opt; {
112    if ( telopt_ok(opt) )
113        return(telopts[telopt_index(opt)]);
114    else
115        return("UNKNOWN");
116}
117#endif /* TELOPT_MACRO */
118
119static int (*p_ttol)(char *,int)=NULL;
120static int (*p_dodebug)(int,char *,char *,long)=NULL;
121static int (*p_dohexdump)(char *,char *,int)=NULL;
122static void (*p_tn_debug)(char *)=NULL;
123static int (*p_vscrnprintf)(char *, ...)=NULL;
124static void * p_k5_context=NULL;
125static unsigned long (*p_reqtelmutex)(unsigned long)=NULL;
126static unsigned long (*p_reltelmutex)(void)=NULL;
127
128unsigned long
129RequestTelnetMutex(unsigned long x)
130{
131    if ( p_reqtelmutex )
132        return p_reqtelmutex(x);
133    return 0;
134}
135
136unsigned long
137ReleaseTelnetMutex(void)
138{
139    if ( p_reltelmutex )
140        return p_reltelmutex();
141    return 0;
142}
143
144int
145ttol(char * s, int n)
146{
147    if ( p_ttol )
148        return(p_ttol(s,n));
149    else
150        return(-1);
151}
152
153int
154dodebug(int flag, char * s1, char * s2, long n)
155{
156    if ( p_dodebug )
157        return(p_dodebug(flag,s1,s2,n));
158    else
159        return(-1);
160}
161
162int
163dohexdump( char * s1, char * s2, int n )
164{
165    if ( p_dohexdump )
166        p_dohexdump(s1,s2,n);
167    return(0);
168}
169
170void
171tn_debug( char * s )
172{
173    if ( p_tn_debug )
174        p_tn_debug(s);
175}
176
177static char myprtfstr[4096];
178int
179Vscrnprintf(const char * format, ...) {
180    int i, len, rc=0;
181    char *cp;
182    va_list ap;
183
184    va_start(ap, format);
185#ifdef NT
186    rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
187#else /* NT */
188    rc = vsprintf(myprtfstr, format, ap);
189#endif /* NT */
190    va_end(ap);
191
192    if ( p_vscrnprintf )
193        return(p_vscrnprintf(myprtfstr));
194    else
195        return(-1);
196}
197
198int
199#ifdef CK_ANSIC
200tn_hex(CHAR * buf, int buflen, CHAR * data, int datalen)
201#else /* CK_ANSIC */
202tn_hex(buf, buflen, data, datalen)
203    CHAR * buf;
204    int buflen;
205    CHAR * data;
206    int datalen;
207#endif /* CK_ANSIC */
208{
209    int i = 0, j = 0, k = 0;
210    CHAR tmp[8];
211#ifdef COMMENT
212    int was_hex = 1;
213
214    for (k=0; k < datalen; k++) {
215        if (data[k] < 32 || data[k] >= 127) {
216            sprintf(tmp,"%s%02X ",was_hex?"":"\" ",data[k]);
217            was_hex = 1;
218        } else {
219            sprintf(tmp,"%s%c",was_hex?"\"":"",data[k]);
220            was_hex = 0;
221        }
222        ckstrncat(buf,tmp,buflen);
223    }
224    if (!was_hex)
225        ckstrncat(buf,"\" ",buflen);
226#else /* COMMENT */
227    if (datalen <= 0 || data == NULL)
228        return(0);
229
230    for (i = 0; i < datalen; i++) {
231        ckstrncat(buf,"\r\n  ",buflen);
232        for (j = 0 ; (j < 16); j++) {
233            if ((i + j) < datalen)
234              sprintf(tmp,
235                      "%s%02x ",
236                      (j == 8 ? "| " : ""),
237                      (CHAR) data[i + j]
238                      );
239            else
240              sprintf(tmp,
241                      "%s   ",
242                      (j == 8 ? "| " : "")
243                      );
244            ckstrncat(buf,tmp,buflen);
245        }
246        ckstrncat(buf," ",buflen);
247        for (k = 0; (k < 16) && ((i + k) < datalen); k++) {
248            sprintf(tmp,
249                     "%s%c",
250                     (k == 8 ? " " : ""),
251                     isprint(data[i + k]) ? data[i + k] : '.'
252                     );
253            ckstrncat(buf,tmp,buflen);
254        }
255        i += j - 1;
256    } /* end for */
257    ckstrncat(buf,"\r\n  ",buflen);
258#endif /* COMMENT */
259    return(strlen(buf));
260}
261
262#ifdef COMMENT
263#define ttol        dll_ttol
264#define dodebug     dll_dodebug
265#define dohexdump   dll_dohexdump
266#define tn_debug    dll_tn_debug
267#define Vscrnprintf dll_vscrnprintf
268#endif /* COMMENT */
269
270char tn_msg[TN_MSG_LEN], hexbuf[TN_MSG_LEN];   /* from ckcnet.c */
271int deblog=1, debses=1, tn_deb=1;
272#else /* CRYPT_DLL */
273extern char tn_msg[], hexbuf[];         /* from ckcnet.c */
274extern int deblog, debses, tn_deb;
275#ifdef MIT_CURRENT
276extern krb5_context k5_context;
277#endif /* MIT_CURRENT */
278#endif /* CRYPT_DLL */
279
280#ifdef LIBDES
281#ifndef UNIX
282#define des_new_random_key            des_random_key
283#define des_set_random_generator_seed des_random_seed
284#endif /* UNIX */
285#define des_fixup_key_parity          des_set_odd_parity
286#ifdef OPENSSL_097
287#define OPENSSL_ENABLE_OLD_DES_SUPPORT
288#include <openssl/des.h>
289#endif /* OPENSSL_097 */
290#else /* LIBDES */
291#ifdef UNIX
292#define des_set_random_generator_seed(x) des_init_random_number_generator(x)
293#endif /* UNIX */
294#ifdef OS2
295#define des_new_random_key            ck_des_new_random_key
296#define des_set_random_generator_seed ck_des_set_random_generator_seed
297#define des_key_sched                 ck_des_key_sched
298#define des_ecb_encrypt               ck_des_ecb_encrypt
299#define des_string_to_key             ck_des_string_to_key
300#define des_fixup_key_parity          ck_des_fixup_key_parity
301#endif /* OS2 */
302#endif /* LIBDES */
303
304#ifdef CK_DES
305/* This code comes from Eric Young's libdes package and is not part   */
306/* of the standard MIT DES library that is part of Kerberos. However, */
307/* it is extremely useful.  So we add it here.                        */
308
309
310/* Weak and semi week keys as take from
311 * %A D.W. Davies
312 * %A W.L. Price
313 * %T Security for Computer Networks
314 * %I John Wiley & Sons
315 * %D 1984
316 * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
317 * (and actual cblock values).
318 */
319#define NUM_WEAK_KEY    16
320static Block weak_keys[NUM_WEAK_KEY]={
321        /* weak keys */
322        {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
323        {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
324        {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
325        {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
326        /* semi-weak keys */
327        {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
328        {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
329        {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
330        {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
331        {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
332        {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
333        {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
334        {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
335        {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
336        {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
337        {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
338        {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
339
340int
341ck_des_is_weak_key(key)
342Block key;
343{
344    int i;
345
346    for (i=0; i<NUM_WEAK_KEY; i++) {
347        /* Added == 0 to comparision, I obviously don't run
348        * this section very often :-(, thanks to
349        * engineering@MorningStar.Com for the fix
350        * eay 93/06/29
351        * Another problem, I was comparing only the first 4
352        * bytes, 97/03/18 */
353        if (memcmp(weak_keys[i],key,sizeof(Block)) == 0)
354            return(1);
355    }
356    return(0);
357}
358
359#ifdef UNIX
360#ifdef LIBDES
361/* These functions are not part of Eric Young's DES library */
362/* _unix_time_gmt_unixsec                                  */
363/* _des_set_random_generator_seed                          */
364/* _des_fixup_key_parity   (added in 0.9.5)                */
365/* _des_new_random_key                                     */
366#include <sys/time.h>
367
368unsigned long
369unix_time_gmt_unixsec (usecptr)
370    unsigned long  *usecptr;
371{
372    struct timeval  now;
373
374    (void) gettimeofday (&now, (struct timezone *)0);
375    if (usecptr)
376        *usecptr = now.tv_usec;
377    return now.tv_sec;
378}
379
380void
381des_set_random_generator_seed(Block B)
382{
383    des_random_seed(B);
384    return;
385}
386
387#ifdef COMMENT
388/* added to openssl in 0.9.5 */
389void
390des_fixup_key_parity(Block B)
391{
392    des_set_odd_parity(B);
393    return;
394}
395#endif /* COMMENT */
396int
397des_new_random_key(Block B)
398{
399    int rc=0;
400    rc = des_random_key(B);
401    return(rc);
402}
403
404#endif /* LIBDES */
405#endif /* UNIX */
406#endif /* CK_DES */
407
408/*
409 * Copyright (c) 1991, 1993
410 *      The Regents of the University of California.  All rights reserved.
411 *
412 * Redistribution and use in source and binary forms, with or without
413 * modification, are permitted provided that the following conditions
414 * are met:
415 * 1. Redistributions of source code must retain the above copyright
416 *    notice, this list of conditions and the following disclaimer.
417 * 2. Redistributions in binary form must reproduce the above copyright
418 *    notice, this list of conditions and the following disclaimer in the
419 *    documentation and/or other materials provided with the distribution.
420 * 3. All advertising materials mentioning features or use of this software
421 *    must display the following acknowledgement:
422 *      This product includes software developed by the University of
423 *      California, Berkeley and its contributors.
424 * 4. Neither the name of the University nor the names of its contributors
425 *    may be used to endorse or promote products derived from this software
426 *    without specific prior written permission.
427 *
428 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
429 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
431 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
432 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
433 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
434 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
435 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
436 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
437 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
438 * SUCH DAMAGE.
439 */
440
441/* based on @(#)encrypt.c       8.1 (Berkeley) 6/4/93 */
442
443/*
444 * Copyright (C) 1990 by the Massachusetts Institute of Technology
445 *
446 * Export of this software from the United States of America may
447 * require a specific license from the United States Government.
448 * It is the responsibility of any person or organization contemplating
449 * export to obtain such a license before exporting.
450 *
451 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
452 * distribute this software and its documentation for any purpose and
453 * without fee is hereby granted, provided that the above copyright
454 * notice appear in all copies and that both that copyright notice and
455 * this permission notice appear in supporting documentation, and that
456 * the name of M.I.T. not be used in advertising or publicity pertaining
457 * to distribution of the software without specific, written prior
458 * permission.  M.I.T. makes no representations about the suitability of
459 * this software for any purpose.  It is provided "as is" without express
460 * or implied warranty.
461 */
462
463#include <stdio.h>
464
465/*
466 * These function pointers point to the current routines
467 * for encrypting and decrypting data.
468 */
469static VOID     (*encrypt_output) P((unsigned char *, int));
470static int      (*decrypt_input) P((int));
471
472#ifdef DEBUG
473static int encrypt_debug_mode = 1;
474static int encrypt_verbose = 1;
475#else
476static int encrypt_verbose = 1;
477static int encrypt_debug_mode = 0;
478#endif
479
480static char dbgbuf [16384];
481
482static int decrypt_mode = 0;
483static int encrypt_mode = 0;
484static int autoencrypt = 1;
485static int autodecrypt = 1;
486static int havesessionkey = 0;
487
488static kstream EncryptKSGlobalHack = NULL;
489static int     EncryptType = ENCTYPE_ANY;
490
491#define typemask(x)     ((x) > 0 ? 1 << ((x)-1) : 0)
492
493static long i_support_encrypt =
494        typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64);
495static long i_support_decrypt =
496        typemask(ENCTYPE_DES_CFB64) | typemask(ENCTYPE_DES_OFB64);
497static long i_wont_support_encrypt = 0;
498static long i_wont_support_decrypt = 0;
499#define I_SUPPORT_ENCRYPT       (i_support_encrypt & ~i_wont_support_encrypt)
500#define I_SUPPORT_DECRYPT       (i_support_decrypt & ~i_wont_support_decrypt)
501
502static long remote_supports_encrypt = 0;
503static long remote_supports_decrypt = 0;
504
505/* Make sure that this list is in order of algorithm strength     */
506/* as it determines the search order for selecting specific       */
507/* encryption choices.  All CFB modes must come before OFB modes. */
508static Encryptions encryptions[] = {
509#ifdef DES_ENCRYPTION
510    { "DES3_CFB64",
511          ENCTYPE_DES3_CFB64,
512          des3_cfb64_encrypt,
513          des3_cfb64_decrypt,
514          des3_cfb64_init,
515          des3_cfb64_start,
516          des3_cfb64_is,
517          des3_cfb64_reply,
518          des3_cfb64_session,
519          des3_cfb64_keyid,
520          NULL },
521#endif /* DES_ENCRYPTION */
522#ifdef CAST_ENCRYPTION
523#ifndef CAST_EXPORT_ENCRYPTION
524    { "CAST128_CFB64",  ENCTYPE_CAST128_CFB64,
525          cast_cfb64_encrypt,
526          cast_cfb64_decrypt,
527          cast_cfb64_init,
528          cast_cfb64_start,
529          cast_cfb64_is,
530          cast_cfb64_reply,
531          cast_cfb64_session,
532          cast_cfb64_keyid,
533          NULL },
534#endif
535#endif
536#ifdef DES_ENCRYPTION
537    { "DES_CFB64",
538          ENCTYPE_DES_CFB64,
539          cfb64_encrypt,
540          cfb64_decrypt,
541          cfb64_init,
542          cfb64_start,
543          cfb64_is,
544          cfb64_reply,
545          cfb64_session,
546          cfb64_keyid,
547          NULL },
548#endif  /* DES_ENCRYPTION */
549#if defined (CAST_EXPORT_ENCRYPTION) || defined(CAST_ENCRYPTION)
550    { "CAST5_40_CFB64", ENCTYPE_CAST5_40_CFB64,
551          castexp_cfb64_encrypt,
552          castexp_cfb64_decrypt,
553          castexp_cfb64_init,
554          castexp_cfb64_start,
555          castexp_cfb64_is,
556          castexp_cfb64_reply,
557          castexp_cfb64_session,
558          castexp_cfb64_keyid,
559          NULL },
560#endif /* CAST_ENCRYPTION */
561#ifdef DES_ENCRYPTION
562    { "DES3_OFB64",
563          ENCTYPE_DES3_OFB64,
564          des3_ofb64_encrypt,
565          des3_ofb64_decrypt,
566          des3_ofb64_init,
567          des3_ofb64_start,
568          des3_ofb64_is,
569          des3_ofb64_reply,
570          des3_ofb64_session,
571          des3_ofb64_keyid,
572          NULL },
573#endif /* DES_ENCRYPTION */
574#ifdef CAST_ENCRYPTION
575#ifndef CAST_EXPORT_ENCRYPTION
576    { "CAST128_OFB64",  ENCTYPE_CAST128_OFB64,
577          cast_ofb64_encrypt,
578          cast_ofb64_decrypt,
579          cast_ofb64_init,
580          cast_ofb64_start,
581          cast_ofb64_is,
582          cast_ofb64_reply,
583          cast_ofb64_session,
584          cast_ofb64_keyid,
585          NULL },
586#endif
587#endif
588#ifdef DES_ENCRYPTION
589    { "DES_OFB64",
590          ENCTYPE_DES_OFB64,
591          ofb64_encrypt,
592          ofb64_decrypt,
593          ofb64_init,
594          ofb64_start,
595          ofb64_is,
596          ofb64_reply,
597          ofb64_session,
598          ofb64_keyid,
599          NULL },
600#endif  /* DES_ENCRYPTION */
601#if defined (CAST_EXPORT_ENCRYPTION) || defined(CAST_ENCRYPTION)
602    { "CAST5_40_OFB64", ENCTYPE_CAST5_40_OFB64,
603          castexp_ofb64_encrypt,
604          castexp_ofb64_decrypt,
605          castexp_ofb64_init,
606          castexp_ofb64_start,
607          castexp_ofb64_is,
608          castexp_ofb64_reply,
609          castexp_ofb64_session,
610          castexp_ofb64_keyid,
611          NULL },
612#endif /* CAST_ENCRYPTION */
613    { 0,0,0,0,0,0,0,0,0,0,0  }
614};
615
616int
617get_crypt_table( struct keytab ** pTable, int * pN )
618{
619    int i=0,n=0;
620
621    if ( *pTable )
622    {
623        for ( i=0 ; i < *pN ; i++ )
624            free( (*pTable)[i].kwd ) ;
625        free ( *pTable )  ;
626    }
627    *pTable = NULL;
628    *pN = 0;
629
630    /* How many encryption types do we have? */
631    while ( encryptions[n].name )
632        n++;
633
634    if ( n )
635    {
636        *pTable = malloc( sizeof(struct keytab) * (n+2) ) ;
637        if ( !(*pTable) )
638            return(0);
639
640#ifdef OS2
641        (*pTable)[0].kwd =strdup("automatic");
642#else /* OS2 */
643        makestr(&tmpstring,"automatic");
644        (*pTable)[0].kwd = tmpstring;
645        tmpstring = NULL;
646#endif /* OS2 */
647        (*pTable)[0].kwval = ENCTYPE_ANY;
648        (*pTable)[0].flgs = 0;
649#ifdef OS2
650        (*pTable)[1].kwd =strdup("none");
651#else /* OS2 */
652        makestr(&tmpstring,"none");
653        (*pTable)[1].kwd = tmpstring;
654        tmpstring = NULL;
655#endif /* OS2 */
656        (*pTable)[1].kwval = 999;
657        (*pTable)[1].flgs = 0;
658        (*pN) = 2;
659
660        for ( i=0 ; i < n ; i++ ) {
661            char * newstr = NULL, * p;
662            int newval = encryptions[i].type;
663            int j = 0, len = 0;
664
665#ifdef OS2
666            newstr = strdup(encryptions[i].name);
667            strlwr(newstr);
668#else /* OS2 */
669            makestr(&tmpstring,encryptions[i].name);
670            newstr = tmpstring;
671            tmpstring = NULL;
672            for (p = newstr; *p; p++) if (isupper(*p)) *p = tolower(*p);
673#endif /* OS2 */
674
675            for (j = 0; j < (*pN); j++) {
676                int tempval = 0;
677                char * tempstr = NULL;
678
679                if ( strcmp( (*pTable)[j].kwd, newstr ) > 0 )
680                {
681                    tempval = (*pTable)[j].kwval;
682                    tempstr = (*pTable)[j].kwd;
683                    (*pTable)[j].kwd = newstr ;
684                    (*pTable)[j].kwval = newval;
685                    newval = tempval;
686                    newstr = tempstr;
687                    (*pTable)[j].flgs = 0;
688                }
689            }
690            (*pTable)[*pN].kwd = newstr ;
691            (*pTable)[*pN].kwval = newval;
692            (*pTable)[*pN].flgs = 0 ;
693            (*pN)++ ;
694        }
695    } else {
696        *pTable = malloc( sizeof(struct keytab) * 2 ) ;
697        if ( !(*pTable) )
698            return(0);
699
700#ifdef OS2
701        (*pTable)[0].kwd =strdup("automatic");
702#else /* OS2 */
703        makestr(&tmpstring,"automatic");
704        (*pTable)[0].kwd = tmpstring;
705        tmpstring = NULL;
706#endif /* OS2 */
707        (*pTable)[0].kwval = ENCTYPE_ANY;
708        (*pTable)[0].flgs = 0;
709#ifdef OS2
710        (*pTable)[1].kwd =strdup("none");
711#else /* OS2 */
712        makestr(&tmpstring,"none");
713        (*pTable)[1].kwd = tmpstring;
714        tmpstring = NULL;
715#endif /* OS2 */
716        (*pTable)[1].kwval = 999;
717        (*pTable)[1].flgs = 0;
718        (*pN) = 2;
719    }
720    return(*pN);
721}
722
723static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPTION,
724                                      ENCRYPT_SUPPORT };
725static unsigned char str_suplen = 0;
726static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPTION };
727static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPTION, 0, IAC, SE };
728
729_PROTOTYP(int  encrypt_request_end, (VOID));
730_PROTOTYP(int  encrypt_request_start, (VOID));
731_PROTOTYP(int  encrypt_enc_keyid, (unsigned char *, int));
732_PROTOTYP(int  encrypt_dec_keyid, (unsigned char *, int));
733_PROTOTYP(int  encrypt_support, (unsigned char *, int));
734_PROTOTYP(int  encrypt_start, (unsigned char *, int));
735_PROTOTYP(int  encrypt_end, (VOID));
736
737_PROTOTYP(int encrypt_ks_stream,(struct kstream_data_block *, /* output */
738                                   struct kstream_data_block *)); /* input */
739
740_PROTOTYP(int decrypt_ks_stream,(struct kstream_data_block *, /* output */
741                                   struct kstream_data_block *)); /* input */
742
743int
744#ifdef CK_ANSIC
745encrypt_ks_stream(struct kstream_data_block *i,
746                  struct kstream_data_block *o)
747#else
748encrypt_ks_stream(i,o)
749    struct kstream_data_block *i; struct kstream_data_block *o;
750#endif
751{
752    /*
753    * this is really quite bogus, since it does an in-place encryption...
754    */
755    if (encrypt_output) {
756        encrypt_output(i->ptr, i->length);
757        return 1;
758    }
759    return 0;
760}
761
762
763int
764#ifdef CK_ANSIC
765decrypt_ks_stream(struct kstream_data_block *i,
766                  struct kstream_data_block *o)
767#else
768decrypt_ks_stream(i,o)
769    struct kstream_data_block *i; struct kstream_data_block *o;
770#endif
771{
772    unsigned int len;
773  /*
774   * this is really quite bogus, since it does an in-place decryption...
775   */
776    if (decrypt_input) {
777        for (len = 0 ; len < i->length ; len++)
778            ((unsigned char *)i->ptr)[len]
779                = decrypt_input(((unsigned char *)i->ptr)[len]);
780        return 1;
781    }
782    return 0;
783}
784
785int
786#ifdef CK_ANSIC
787decrypt_ks_hack(unsigned char *buf, int cnt)
788#else
789decrypt_ks_hack(buf,cnt) unsigned char *buf; int cnt;
790#endif
791{
792    int len;
793  /*
794   * this is really quite bogus, since it does an in-place decryption...
795   */
796    for (len = 0 ; len < cnt ; len++)
797        buf[len] = decrypt_input(buf[len]);
798
799#ifdef DEBUG
800    hexdump("decrypt ks hack", buf, cnt);
801#endif
802    return 1;
803}
804
805
806/*
807 * parsedat[0] == the suboption we might be negotiating,
808 */
809int
810#ifdef CK_ANSIC
811encrypt_parse(unsigned char *parsedat, int end_sub)
812#else
813encrypt_parse(parsedat,end_sub) unsigned char *parsedat; int end_sub;
814#endif
815{
816    int rc = 0;
817
818    switch(parsedat[1]) {
819    case ENCRYPT_START:
820        rc = encrypt_start(parsedat + 2, end_sub - 2);
821        break;
822    case ENCRYPT_END:
823        rc = encrypt_end();
824        break;
825    case ENCRYPT_SUPPORT:
826        rc = encrypt_support(parsedat + 2, end_sub - 2);
827        break;
828    case ENCRYPT_REQSTART:
829        rc = encrypt_request_start();
830        break;
831    case ENCRYPT_REQEND:
832        /*
833        * We can always send an REQEND so that we cannot
834        * get stuck encrypting.  We should only get this
835        * if we have been able to get in the correct mode
836        * anyhow.
837        */
838        rc = encrypt_request_end();
839        break;
840    case ENCRYPT_IS:
841        rc = encrypt_is(parsedat + 2, end_sub - 2);
842        break;
843    case ENCRYPT_REPLY:
844        rc = encrypt_reply(parsedat + 2, end_sub - 2);
845        break;
846    case ENCRYPT_ENC_KEYID:
847        rc = encrypt_enc_keyid(parsedat + 2, end_sub - 2);
848        break;
849    case ENCRYPT_DEC_KEYID:
850        rc = encrypt_dec_keyid(parsedat + 2, end_sub - 2);
851        break;
852    default:
853        rc = -1;
854        break;
855    }
856    return(rc);
857}
858
859/* XXX */
860Encryptions *
861#ifdef CK_ANSIC
862findencryption(int type)
863#else
864findencryption(type) int type;
865#endif
866{
867    Encryptions *ep = encryptions;
868
869    if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type)))
870        return(0);
871    while (ep->type && ep->type != type)
872        ++ep;
873    return(ep->type ? ep : 0);
874}
875
876Encryptions *
877#ifdef CK_ANSIC
878finddecryption(int type)
879#else
880finddecryption(type) int type;
881#endif
882{
883    Encryptions *ep = encryptions;
884
885    if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type)))
886        return(0);
887    while (ep->type && ep->type != type)
888        ++ep;
889    return(ep->type ? ep : 0);
890}
891
892#define MAXKEYLEN 64
893
894static struct key_info {
895    unsigned char keyid[MAXKEYLEN];
896    int keylen;
897    int dir;
898    int *modep;
899    Encryptions *(*getcrypt)();
900} ki[2] = {
901    { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption },
902    { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption },
903};
904
905VOID
906#ifdef CK_ANSIC
907encrypt_init(kstream iks, int type)
908#else
909encrypt_init(iks, type) kstream iks; int type;
910#endif
911{
912    Encryptions *ep = encryptions;
913
914    i_support_encrypt = i_support_decrypt = 0;
915    remote_supports_encrypt = remote_supports_decrypt = 0;
916    i_wont_support_encrypt = i_wont_support_decrypt = 0;
917    encrypt_mode = 0;
918    decrypt_mode = 0;
919    encrypt_output = NULL;
920    decrypt_input = NULL;
921    ki[0].keylen = 0;
922    memset(ki[0].keyid,0,MAXKEYLEN);
923    ki[1].keylen = 0;
924    memset(ki[1].keyid,0,MAXKEYLEN);
925    havesessionkey = 0;
926    autoencrypt = 1;
927    autodecrypt = 1;
928
929    EncryptKSGlobalHack = iks;
930    EncryptType = type;
931
932    str_send[0] = IAC;
933    str_send[1] = SB;
934    str_send[2] = TELOPT_ENCRYPTION;
935    str_send[3] = ENCRYPT_SUPPORT;
936    str_suplen = 4;
937
938    while (ep->type) {
939        if ( EncryptType == ENCTYPE_ANY ||
940             EncryptType == ep->type ) {
941#ifdef DEBUG
942            if (encrypt_debug_mode) {
943                sprintf(dbgbuf, ">>>I will support %s\n",
944                         ENCTYPE_NAME(ep->type));       /* safe */
945                debug(F110,"encrypt_init",dbgbuf,0);
946            }
947#endif
948            i_support_encrypt |= typemask(ep->type);
949            i_support_decrypt |= typemask(ep->type);
950            if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
951                if ((str_send[str_suplen++] = ep->type) == IAC)
952                    str_send[str_suplen++] = IAC;
953        }
954        if (ep->init)
955            (*ep->init)(0);
956        ++ep;
957    }
958    str_send[str_suplen++] = IAC;
959    str_send[str_suplen++] = SE;
960}
961
962VOID
963#ifdef CK_ANSIC
964encrypt_send_support(VOID)
965#else
966encrypt_send_support()
967#endif
968{
969    Encryptions *ep = encryptions;
970
971#ifdef CK_SSL
972    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
973        return;
974#endif /* CK_SSL */
975
976    str_send[0] = IAC;
977    str_send[1] = SB;
978    str_send[2] = TELOPT_ENCRYPTION;
979    str_send[3] = ENCRYPT_SUPPORT;
980    str_suplen = 4;
981
982    while (ep->type) {
983        if ( EncryptType == ENCTYPE_ANY ||
984             EncryptType == ep->type ) {
985#ifdef DEBUG
986            if (encrypt_debug_mode) {
987                sprintf(dbgbuf, ">>>I will support %s\n",
988                         ENCTYPE_NAME(ep->type));               /* safe */
989                debug(F110,"encrypt_send_support",dbgbuf,0);
990            }
991#endif
992            if ((i_wont_support_decrypt & typemask(ep->type)) == 0)
993                if ((str_send[str_suplen++] = ep->type) == IAC)
994                    str_send[str_suplen++] = IAC;
995        }
996        ++ep;
997    }
998    str_send[str_suplen++] = IAC;
999    str_send[str_suplen++] = SE;
1000
1001    /*
1002    * If the user has requested that decryption start
1003    * immediatly, then send a "REQUEST START" before
1004    * we negotiate the type.
1005    */
1006    if (autodecrypt)
1007        encrypt_send_request_start();
1008
1009    if (deblog || tn_deb || debses) {
1010        int i;
1011        sprintf(tn_msg,"TELNET SENT SB %s SUPPORT ",
1012                 TELOPT(TELOPT_ENCRYPTION));                    /* safe */
1013        for ( i=4;i<str_suplen-2;i++ ) {
1014            if ( str_send[i] == IAC ) {
1015                ckstrncat(tn_msg,"IAC ",TN_MSG_LEN);
1016                i++;
1017            }
1018            ckstrncat(tn_msg,ENCTYPE_NAME(str_send[i]),TN_MSG_LEN);
1019            ckstrncat(tn_msg," ",TN_MSG_LEN);
1020        }
1021        ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
1022        debug(F100,tn_msg,"",0);
1023        if (tn_deb || debses) tn_debug(tn_msg);
1024    }
1025#ifdef OS2
1026    RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1027#endif
1028    ttol(str_send, str_suplen);
1029#ifdef OS2
1030    ReleaseTelnetMutex();
1031#endif
1032
1033    str_suplen = 0;
1034}
1035
1036/*
1037 * Called when ENCRYPT SUPPORT is received.
1038 */
1039int
1040#ifdef CK_ANSIC
1041encrypt_support(unsigned char *_typelist, int _cnt)
1042#else
1043encrypt_support(_typelist, _cnt) unsigned char * _typelist; int _cnt;
1044#endif
1045{
1046    register int type, use_type = 0;
1047    unsigned char * typelist = _typelist;
1048    int cnt = _cnt;
1049    Encryptions *ep;
1050
1051    debug(F111,"encrypt_support","cnt",cnt);
1052
1053  /*
1054   * Forget anything the other side has previously told us.
1055   */
1056    remote_supports_decrypt = 0;
1057
1058    while (cnt-- > 0) {
1059        type = *typelist++;
1060        if ( EncryptType == ENCTYPE_ANY ||
1061             EncryptType == type ) {
1062#ifdef DEBUG
1063            if (encrypt_debug_mode) {
1064                sprintf(dbgbuf, ">>>Remote supports %s (%d)\n",
1065                         ENCTYPE_NAME(type), type);             /* safe */
1066                debug(F110,"encrypt_support",dbgbuf,0);
1067            }
1068#endif
1069            if ((type < ENCTYPE_CNT) &&
1070                 (I_SUPPORT_ENCRYPT & typemask(type))) {
1071                remote_supports_decrypt |= typemask(type);
1072                if (use_type == 0)
1073                    use_type = type;
1074            }
1075        }
1076    }
1077    if (use_type) {
1078        ep = findencryption(use_type);
1079        if (!ep) {
1080            debug(F111,"encrypt_support","findencryption == NULL",use_type);
1081            return(-1);
1082        }
1083        type = ep->start ? (*ep->start)(DIR_ENCRYPT, 0) : 0;
1084#ifdef DEBUG
1085        if (encrypt_debug_mode) {
1086            sprintf(dbgbuf, ">>>(*ep->start)() %s returned %d (%s)\n",
1087                     ENCTYPE_NAME(use_type), type,
1088                     ENCRYPT_NAME(type));                       /* safe */
1089            debug(F110,"encrypt_support",dbgbuf,0);
1090        }
1091#endif
1092        if (type < 0) {
1093            debug(F111,"encrypt_support","type < 0",type);
1094            return(-1);
1095        }
1096        encrypt_mode = use_type;
1097        if (type == 0)
1098            encrypt_start_output(use_type);
1099        debug(F111,"encrypt_support","success",type);
1100        return(0);
1101    }
1102    debug(F111,"encrypt_support","failed",use_type);
1103    return(-1);
1104}
1105
1106int
1107#ifdef CK_ANSIC
1108encrypt_is(unsigned char *data, int cnt)
1109#else
1110encrypt_is(data, cnt) unsigned char *data; int cnt;
1111#endif /* CK_ANSIC */
1112{
1113    Encryptions *ep;
1114    register int type, ret;
1115
1116    if (--cnt < 0)
1117        return(-1);
1118    type = *data++;
1119    if (type < ENCTYPE_CNT)
1120        remote_supports_encrypt |= typemask(type);
1121    if (!(ep = finddecryption(type))) {
1122#ifdef DEBUG
1123        if (encrypt_debug_mode) {
1124            sprintf(dbgbuf, ">>>encrypt_is:  "
1125                     "Can't find type %s (%d) for initial negotiation\n",
1126                     ENCTYPE_NAME_OK(type)
1127                     ? ENCTYPE_NAME(type) : "(unknown)",
1128                     type);                                     /* safe */
1129            debug(F110,"encrypt_is",dbgbuf,0);
1130        }
1131#endif
1132        return(-1);
1133    }
1134    if (!ep->is) {
1135#ifdef DEBUG
1136        if (encrypt_debug_mode) {
1137            sprintf(dbgbuf, ">>>encrypt_is:  "
1138                     "No initial negotiation needed for type %s (%d)\n",
1139                     ENCTYPE_NAME_OK(type)
1140                     ? ENCTYPE_NAME(type) : "(unknown)",
1141                     type);                                     /* safe */
1142            debug(F110,"encrypt_is",dbgbuf,0);
1143        }
1144#endif
1145        ret = 0;
1146    } else {
1147        ret = (*ep->is)(data, cnt);
1148#ifdef DEBUG
1149        if (encrypt_debug_mode) {
1150            sprintf(dbgbuf, "encrypt_is:  "
1151                     "(*ep->is)(%x, %d) returned %s(%d)\n", data, cnt,
1152                     (ret < 0) ? "FAIL " :
1153                     (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); /* safe */
1154            debug(F110,"encrypt_is",dbgbuf,0);
1155        }
1156#endif
1157    }
1158    if (ret < 0) {
1159        autodecrypt = 0;
1160        return(-1);
1161    } else {
1162        decrypt_mode = type;
1163        if (ret == 0 && autodecrypt) {
1164            encrypt_send_request_start();
1165        }
1166    }
1167    return(0);
1168}
1169
1170int
1171#ifdef CK_ANSIC
1172encrypt_reply(unsigned char *data, int cnt)
1173#else
1174encrypt_reply(data, cnt) unsigned char *data; int cnt;
1175#endif
1176{
1177    Encryptions *ep;
1178    register int ret, type;
1179
1180    if (--cnt < 0)
1181        return(-1);
1182    type = *data++;
1183    if (!(ep = findencryption(type))) {
1184#ifdef DEBUG
1185        if (encrypt_debug_mode) {
1186            sprintf(dbgbuf,
1187                    ">>>Can't find type %s (%d) for initial negotiation\n",
1188                     ENCTYPE_NAME_OK(type)
1189                     ? ENCTYPE_NAME(type) : "(unknown)",
1190                     type);                                     /* safe */
1191            debug(F110,"encrypt_reply",dbgbuf,0);
1192        }
1193#endif
1194        return(-1);
1195    }
1196    if (!ep->reply) {
1197#ifdef DEBUG
1198        if (encrypt_debug_mode) {
1199      sprintf(dbgbuf, ">>>No initial negotiation needed for type %s (%d)\n",
1200               ENCTYPE_NAME_OK(type)
1201               ? ENCTYPE_NAME(type) : "(unknown)",
1202               type);                                           /* safe */
1203            debug(F110,"encrypt_reply",dbgbuf,0);
1204        }
1205#endif
1206        ret = 0;
1207    } else {
1208        ret = (*ep->reply)(data, cnt);
1209#ifdef DEBUG
1210        if (encrypt_debug_mode) {
1211            sprintf(dbgbuf, "(*ep->reply)(%x, %d) returned %s(%d)\n",
1212                     data, cnt,
1213                     (ret < 0) ? "FAIL " :
1214                     (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); /* safe */
1215            debug(F110,"encrypt_reply",dbgbuf,0);
1216        }
1217#endif
1218    }
1219#ifdef DEBUG
1220    if (encrypt_debug_mode) {
1221        sprintf(dbgbuf, ">>>encrypt_reply returned %d\n", ret); /* safe */
1222        debug(F110,"encrypt_reply",dbgbuf,0);
1223    }
1224#endif
1225    if (ret < 0) {
1226        autoencrypt = 0;
1227        return(-1);
1228    } else {
1229        encrypt_mode = type;
1230        if (ret == 0 && autoencrypt)
1231            encrypt_start_output(type);
1232    }
1233    return(0);
1234}
1235
1236/*
1237 * Called when a ENCRYPT START command is received.
1238 */
1239int
1240#ifdef CK_ANSIC
1241encrypt_start(unsigned char *data, int cnt)
1242#else
1243encrypt_start(data, cnt) unsigned char *data; int cnt;
1244#endif
1245{
1246    Encryptions *ep;
1247
1248    if (!decrypt_mode) {
1249        /*
1250        * Something is wrong.  We should not get a START
1251        * command without having already picked our
1252        * decryption scheme.  Send a REQUEST-END to
1253        * attempt to clear the channel...
1254        */
1255        encrypt_send_request_end();
1256        printf("Kerberos authentication error!\n%s\n",
1257                "Warning, Cannot decrypt input stream!!!");
1258        return(-1);
1259    }
1260
1261    if (ep = finddecryption(decrypt_mode)) {
1262        if ( decrypt_input != ep->input ) {
1263            decrypt_input = ep->input;
1264            EncryptKSGlobalHack->decrypt = decrypt_ks_stream;
1265            EncryptKSGlobalHack->decrypt_type = ep->type;
1266
1267            if (encrypt_verbose) {
1268                sprintf(dbgbuf, "Input is now decrypted with type %s",
1269                         ENCTYPE_NAME(decrypt_mode));           /* safe */
1270                debug(F110,"encrypt_start",dbgbuf,0);
1271                printf("%s\n",dbgbuf);
1272            }
1273#ifdef DEBUG
1274            if (encrypt_debug_mode) {
1275                sprintf(dbgbuf, ">>>Start to decrypt input with type %s",
1276                         ENCTYPE_NAME(decrypt_mode));           /* safe */
1277                debug(F110,"ck_crp",dbgbuf,0);
1278            }
1279#endif
1280        }
1281    } else {
1282        char buf[1024];
1283        sprintf(buf, "Warning, Cannot decrypt type %s (%d)!!!",
1284                  ENCTYPE_NAME_OK(decrypt_mode)
1285                  ? ENCTYPE_NAME(decrypt_mode) : "(unknown)",
1286                  decrypt_mode);                                /* safe */
1287        printf("Kerberos authentication error!\n%s\n",buf);
1288        encrypt_send_request_end();
1289        return(-1);
1290    }
1291    return(0);
1292}
1293
1294int
1295#ifdef CK_ANSIC
1296encrypt_session_key(Session_Key *key, int server)
1297#else
1298encrypt_session_key(key, server) Session_Key *key; int server;
1299#endif
1300{
1301    Encryptions *ep = encryptions;
1302
1303    if (havesessionkey)
1304        return(0);
1305
1306    havesessionkey = 1;
1307
1308    while (ep->type) {
1309        debug(F111,"encrypt_session_key",ep->name,ep->type);
1310        if (ep->session) {
1311            if ((*ep->session)(key, server) < 0) {
1312                i_wont_support_encrypt |= typemask(ep->type);
1313                i_wont_support_decrypt |= typemask(ep->type);
1314            }
1315        }
1316        ++ep;
1317    }
1318    debug(F111,"encrypt_session_key (done)",ep->name,ep->type);
1319    return(0);
1320}
1321
1322/*
1323 * Called when ENCRYPT END is received.
1324 */
1325int
1326#ifdef CK_ANSIC
1327encrypt_end(VOID)
1328#else
1329encrypt_end()
1330#endif
1331{
1332    decrypt_input = NULL;
1333    EncryptKSGlobalHack->decrypt = NULL;
1334    EncryptKSGlobalHack->decrypt_type = ENCTYPE_ANY;
1335#ifdef DEBUG
1336    if (encrypt_debug_mode) {
1337        sprintf(dbgbuf, ">>>Input is back to clear text");      /* safe */
1338        debug(F110,"encrypt_end",dbgbuf,0);
1339    }
1340#endif
1341    if (encrypt_verbose) {
1342        sprintf(dbgbuf, "Input is now clear text");             /* safe */
1343        debug(F110,"encrypt_end",dbgbuf,0);
1344        printf("%s\n",dbgbuf);
1345    }
1346    return(0);
1347}
1348
1349/*
1350 * Called when ENCRYPT REQUEST-END is received.
1351 */
1352int
1353#ifdef CK_ANSIC
1354encrypt_request_end(VOID)
1355#else
1356encrypt_request_end()
1357#endif
1358{
1359    encrypt_send_end();
1360    return(0);
1361}
1362
1363/*
1364 * Called when ENCRYPT REQUEST-START is received.  If we receive
1365 * this before a type is picked, then that indicates that the
1366 * other side wants us to start encrypting data as soon as we
1367 * can.
1368 */
1369int
1370#ifdef CK_ANSIC
1371encrypt_request_start(VOID)
1372#else
1373encrypt_request_start()
1374#endif
1375{
1376    if (encrypt_mode != 0)
1377        encrypt_start_output(encrypt_mode);
1378    return(0);
1379}
1380
1381static unsigned char str_keyid[(MAXKEYLEN*2)+5] = {
1382    IAC, SB, TELOPT_ENCRYPTION
1383};
1384_PROTOTYP(int encrypt_keyid,(struct key_info *,unsigned char *,int));
1385
1386int
1387#ifdef CK_ANSIC
1388encrypt_enc_keyid(unsigned char *keyid, int len)
1389#else
1390encrypt_enc_keyid(keyid, len) unsigned char *keyid; int len;
1391#endif
1392{
1393    return(encrypt_keyid(&ki[1], keyid, len));
1394}
1395
1396int
1397#ifdef CK_ANSIC
1398encrypt_dec_keyid(unsigned char *keyid, int len)
1399#else
1400encrypt_dec_keyid(keyid, len) unsigned char *keyid; int len;
1401#endif /* CK_ANSIC */
1402{
1403    return(encrypt_keyid(&ki[0], keyid, len));
1404}
1405
1406int
1407#ifdef CK_ANSIC
1408encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len)
1409#else
1410encrypt_keyid(kp, keyid, len)
1411    struct key_info *kp; unsigned char *keyid; int len;
1412#endif
1413{
1414    Encryptions *ep;
1415    int dir = kp->dir;
1416    register int ret = 0;
1417
1418    if (!(ep = (*kp->getcrypt)(*kp->modep))) {
1419        if (len == 0)
1420            return(-1);
1421        kp->keylen = 0;
1422    } else if (len == 0 || len > MAXKEYLEN) {
1423        /*
1424        * Empty option or Key too long, indicates a failure.
1425        */
1426        if (kp->keylen == 0)
1427            return(-1);
1428        kp->keylen = 0;
1429        if (ep->keyid)
1430            (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
1431
1432    } else if ((len != kp->keylen) || (memcmp(keyid, kp->keyid, len) != 0)) {
1433        /*
1434        * Length or contents are different
1435        */
1436        kp->keylen = len;
1437        memcpy(kp->keyid, keyid, len);          /* length < MAXKEYLEN */
1438        if (ep->keyid)
1439            (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen);
1440    } else {
1441        if (ep->keyid)
1442            ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen);
1443        if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt)
1444            encrypt_start_output(*kp->modep);
1445        return(0);
1446    }
1447
1448    encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0);
1449    return(0);
1450}
1451
1452int
1453#ifdef CK_ANSIC
1454encrypt_send_keyid(int dir, unsigned char *keyid, int keylen, int saveit)
1455#else
1456encrypt_send_keyid(dir, keyid, keylen, saveit)
1457     int dir; unsigned char *keyid; int keylen; int saveit;
1458#endif
1459{
1460    unsigned char *strp;
1461
1462#ifdef CK_SSL
1463    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
1464        return(0);
1465#endif /* CK_SSL */
1466
1467    str_keyid[3] = (dir == DIR_ENCRYPT)
1468        ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID;
1469    if (saveit && keylen <= MAXKEYLEN) {
1470        struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1];
1471        memcpy(kp->keyid, keyid, keylen);
1472        kp->keylen = keylen;
1473    }
1474
1475    for (strp = &str_keyid[4]; keylen > 0; --keylen) {
1476        if ((*strp++ = *keyid++) == IAC)
1477            *strp++ = IAC;
1478    }
1479    *strp++ = IAC;
1480    *strp++ = SE;
1481
1482    if (deblog || tn_deb || debses) {
1483        int i;
1484        sprintf(tn_msg,"TELNET SENT SB %s %s ",
1485                 TELOPT(TELOPT_ENCRYPTION),
1486                 (dir == DIR_ENCRYPT) ? "ENC-KEYID" : "DEC-KEYID"); /* safe */
1487        tn_hex(tn_msg,TN_MSG_LEN,&str_keyid[4],strp-str_keyid-2-4);
1488        ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
1489        debug(F100,tn_msg,"",0);
1490        if (tn_deb || debses) tn_debug(tn_msg);
1491    }
1492#ifdef OS2
1493    RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1494#endif
1495    ttol(str_keyid, strp - str_keyid);
1496#ifdef OS2
1497    ReleaseTelnetMutex();
1498#endif
1499    return(0);
1500}
1501
1502VOID
1503#ifdef CK_ANSIC
1504encrypt_auto(int on)
1505#else
1506encrypt_auto(on) int on;
1507#endif
1508{
1509    if (on < 0)
1510        autoencrypt ^= 1;
1511    else
1512        autoencrypt = on ? 1 : 0;
1513}
1514
1515VOID
1516#ifdef CK_ANSIC
1517decrypt_auto(int on)
1518#else
1519decrypt_auto(on) int on;
1520#endif
1521{
1522    if (on < 0)
1523        autodecrypt ^= 1;
1524    else
1525        autodecrypt = on ? 1 : 0;
1526}
1527
1528VOID
1529#ifdef CK_ANSIC
1530encrypt_start_output(int type)
1531#else
1532encrypt_start_output(type) int type;
1533#endif
1534{
1535    Encryptions *ep;
1536    register unsigned char *p;
1537    register int i;
1538
1539#ifdef CK_SSL
1540    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
1541        return;
1542#endif /* CK_SSL */
1543
1544    if (!(ep = findencryption(type))) {
1545#ifdef DEBUG
1546        if (encrypt_debug_mode) {
1547            sprintf(dbgbuf, ">>>Can't encrypt with type %s (%d)\n",
1548                     ENCTYPE_NAME_OK(type)
1549                     ? ENCTYPE_NAME(type) : "(unknown)",
1550                     type);                                     /* safe */
1551            debug(F110,"encrypt_start_output",dbgbuf,0);
1552        }
1553#endif
1554        return;
1555    }
1556    if (ep->start) {
1557        i = (*ep->start)(DIR_ENCRYPT, 0);
1558#ifdef DEBUG
1559        if (encrypt_debug_mode) {
1560            sprintf(dbgbuf, ">>>Encrypt start: %s (%d) %s\n",
1561                     (i < 0) ? "failed" :
1562                     "initial negotiation in progress",
1563                     i, ENCTYPE_NAME(type));                    /* safe */
1564            debug(F110,"encrypt_start_output",dbgbuf,0);
1565        }
1566#endif
1567        if (i)
1568            return;
1569    }
1570
1571    if ( encrypt_output != ep->output ) {
1572        p = str_start;
1573        *p++ = IAC;
1574        *p++ = SB;
1575        *p++ = TELOPT_ENCRYPTION;
1576        *p++ = ENCRYPT_START;
1577        for (i = 0; i < ki[0].keylen; ++i) {
1578            if (( *p++ = ki[0].keyid[i]) == IAC)
1579                *p++ = IAC;
1580        }
1581        *p++ = IAC;
1582        *p++ = SE;
1583
1584        if (deblog || tn_deb || debses) {
1585            int i;
1586            sprintf(tn_msg,"TELNET SENT SB %s START ",
1587                     TELOPT(TELOPT_ENCRYPTION));                /* safe */
1588            tn_hex(tn_msg,TN_MSG_LEN,&str_start[4],p-str_start-2-4);
1589            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
1590            debug(F100,tn_msg,"",0);
1591            if (tn_deb || debses) tn_debug(tn_msg);
1592        }
1593#ifdef OS2
1594        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1595#endif
1596        ttol(str_start, p - str_start);
1597#ifdef OS2
1598        ReleaseTelnetMutex();
1599#endif
1600
1601  /*
1602   * If we are already encrypting in some mode, then
1603   * encrypt the ring (which includes our request) in
1604   * the old mode, mark it all as "clear text" and then
1605   * switch to the new mode.
1606   */
1607        encrypt_output = ep->output;
1608        EncryptKSGlobalHack->encrypt = encrypt_ks_stream;
1609        EncryptKSGlobalHack->encrypt_type = type;
1610        encrypt_mode = type;
1611#ifdef DEBUG
1612        if (encrypt_debug_mode) {
1613            sprintf(dbgbuf, ">>>Started to encrypt output with type %s",
1614                     ENCTYPE_NAME(type));                       /* safe */
1615            debug(F110,"encrypt_start_output",dbgbuf,0);
1616        }
1617#endif
1618        if (encrypt_verbose) {
1619            sprintf(dbgbuf, "Output is now encrypted with type %s",
1620                     ENCTYPE_NAME(type));                       /* safe */
1621            debug(F110,"encrypt_start_output",dbgbuf,0);
1622            printf("%s\n",dbgbuf);
1623        }
1624    }
1625}
1626
1627VOID
1628#ifdef CK_ANSIC
1629encrypt_send_end(VOID)
1630#else
1631encrypt_send_end()
1632#endif
1633{
1634#ifdef CK_SSL
1635    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
1636        return;
1637#endif /* CK_SSL */
1638
1639    if (!encrypt_output)
1640        return;
1641
1642    str_end[0] = IAC;
1643    str_end[1] = SB;
1644    str_end[2] = TELOPT_ENCRYPTION;
1645    str_end[3] = ENCRYPT_END;
1646    str_end[4] = IAC;
1647    str_end[5] = SE;
1648
1649    if (deblog || tn_deb || debses) {
1650        int i;
1651        sprintf(tn_msg,"TELNET SENT SB %s END IAC SE",
1652                 TELOPT(TELOPT_ENCRYPTION));                    /* safe */
1653        debug(F100,tn_msg,"",0);
1654        if (tn_deb || debses) tn_debug(tn_msg);
1655    }
1656#ifdef OS2
1657    RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1658#endif
1659    ttol(str_end, sizeof(str_end));
1660#ifdef OS2
1661    ReleaseTelnetMutex();
1662#endif
1663
1664    encrypt_output = 0;
1665    EncryptKSGlobalHack->encrypt = NULL;
1666    EncryptKSGlobalHack->encrypt_type = ENCTYPE_ANY;
1667#ifdef DEBUG
1668    if (encrypt_debug_mode) {
1669        sprintf(dbgbuf, ">>>Output is back to clear text");     /* safe */
1670        debug(F110,"encrypt_send_end",dbgbuf,0);
1671    }
1672#endif
1673    if (encrypt_verbose) {
1674        sprintf(dbgbuf, "Output is now clear text");            /* safe */
1675        debug(F110,"encrypt_send_end",dbgbuf,0);
1676        printf("%s\n",dbgbuf);
1677    }
1678}
1679
1680VOID
1681#ifdef CK_ANSIC
1682encrypt_send_request_start(VOID)
1683#else
1684encrypt_send_request_start()
1685#endif
1686{
1687    register unsigned char *p;
1688    register int i;
1689
1690#ifdef CK_SSL
1691    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
1692        return;
1693#endif /* CK_SSL */
1694
1695    p = str_start;
1696    *p++ = IAC;
1697    *p++ = SB;
1698    *p++ = TELOPT_ENCRYPTION;
1699    *p++ = ENCRYPT_REQSTART;
1700    for (i = 0; i < ki[1].keylen; ++i) {
1701        if (( *p++ = ki[1].keyid[i]) == IAC)
1702            *p++ = IAC;
1703    }
1704    *p++ = IAC;
1705    *p++ = SE;
1706
1707    if (deblog || tn_deb || debses) {
1708        int i;
1709        sprintf(tn_msg,"TELNET SENT SB %s REQUEST-START ",
1710                 TELOPT(TELOPT_ENCRYPTION));                    /* safe */
1711        tn_hex(tn_msg,TN_MSG_LEN,&str_start[4],p-str_start-2-4);
1712        ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
1713        debug(F100,tn_msg,"",0);
1714        if (tn_deb || debses) tn_debug(tn_msg);
1715    }
1716#ifdef OS2
1717    RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1718#endif
1719    ttol(str_start, p - str_start);
1720#ifdef OS2
1721    ReleaseTelnetMutex();
1722#endif
1723
1724    if (encrypt_debug_mode) {
1725        sprintf(dbgbuf, ">>>Request input to be encrypted\n");  /* safe */
1726        debug(F110,"encrypt_send_request_start",dbgbuf,0);
1727    }
1728}
1729
1730VOID
1731#ifdef CK_ANSIC
1732encrypt_send_request_end(VOID)
1733#else
1734encrypt_send_request_end()
1735#endif
1736{
1737#ifdef CK_SSL
1738    if (TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
1739        return;
1740#endif /* CK_SSL */
1741
1742    str_end[0] = IAC;
1743    str_end[1] = SB;
1744    str_end[2] = TELOPT_ENCRYPTION;
1745    str_end[3] = ENCRYPT_REQEND;
1746    str_end[4] = IAC;
1747    str_end[5] = SE;
1748
1749    if (deblog || tn_deb || debses) {
1750        int i;
1751        sprintf(tn_msg,"TELNET SENT SB %s REQEND IAC SE",
1752                 TELOPT(TELOPT_ENCRYPTION));                    /* safe */
1753        debug(F100,tn_msg,"",0);
1754        if (tn_deb || debses) tn_debug(tn_msg);
1755    }
1756#ifdef OS2
1757    RequestTelnetMutex( SEM_INDEFINITE_WAIT );
1758#endif
1759    ttol(str_end, sizeof(str_end));
1760#ifdef OS2
1761    ReleaseTelnetMutex();
1762#endif
1763
1764    if (encrypt_debug_mode) {
1765        sprintf(dbgbuf, ">>>Request input to be clear text\n"); /* safe */
1766        debug(F110,"encrypt_send_request_end",dbgbuf,0);
1767    }
1768}
1769
1770int
1771#ifdef CK_ANSIC
1772encrypt_is_encrypting(VOID)
1773#else
1774encrypt_is_encrypting()
1775#endif
1776{
1777    if (encrypt_output)
1778        return 1;
1779    return 0;
1780}
1781
1782int
1783#ifdef CK_ANSIC
1784encrypt_is_decrypting(VOID)
1785#else
1786encrypt_is_decrypting()
1787#endif
1788{
1789    if (decrypt_input)
1790        return 1;
1791    return 0;
1792}
1793
1794#ifdef DEBUG
1795void
1796encrypt_debug(mode)
1797     int mode;
1798{
1799    encrypt_debug_mode = mode;
1800}
1801#endif
1802
1803#ifdef CK_DES
1804/*-
1805 * Copyright (c) 1991, 1993
1806 *      The Regents of the University of California.  All rights reserved.
1807 *
1808 * Redistribution and use in source and binary forms, with or without
1809 * modification, are permitted provided that the following conditions
1810 * are met:
1811 * 1. Redistributions of source code must retain the above copyright
1812 *    notice, this list of conditions and the following disclaimer.
1813 * 2. Redistributions in binary form must reproduce the above copyright
1814 *    notice, this list of conditions and the following disclaimer in the
1815 *    documentation and/or other materials provided with the distribution.
1816 * 3. All advertising materials mentioning features or use of this software
1817 *    must display the following acknowledgement:
1818 *      This product includes software developed by the University of
1819 *      California, Berkeley and its contributors.
1820 * 4. Neither the name of the University nor the names of its contributors
1821 *    may be used to endorse or promote products derived from this software
1822 *    without specific prior written permission.
1823 *
1824 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1825 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1826 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1827 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1828 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1829 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1830 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1831 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1832 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1833 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1834 * SUCH DAMAGE.
1835 */
1836
1837/* based on @(#)enc_des.c       8.1 (Berkeley) 6/4/93 */
1838
1839#define CFB     0
1840#define OFB     1
1841
1842#define NO_SEND_IV      1
1843#define NO_RECV_IV      2
1844#define NO_KEYID        4
1845#define IN_PROGRESS     (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
1846#define SUCCESS         0
1847#define xFAILED         -1
1848
1849Schedule test_sched;
1850
1851struct des_stinfo {
1852    Block               str_output;
1853    Block               str_feed;
1854    Block               str_iv;
1855    Block               str_ikey;
1856#ifdef MIT_CURRENT
1857    unsigned char       str_keybytes[8];
1858    krb5_keyblock       str_key;
1859#else /* MIT_CURRENT */
1860    Schedule            str_sched;
1861    int                 str_index;
1862#endif /* MIT_CURRENT */
1863    int                 str_flagshift;
1864};
1865
1866struct des_fb {
1867#ifndef MIT_CURRENT
1868    Block krbdes_key;
1869    Schedule krbdes_sched;
1870#endif /* MIT_CURRENT */
1871    Block temp_feed;
1872    unsigned char fb_feed[64];
1873    int need_start;
1874    int state[2];
1875    int keyid[2];
1876    int once;
1877#ifdef MIT_CURRENT
1878    int validkey;
1879#endif /* MIT_CURRENT */
1880    struct des_stinfo  streams[2];
1881};
1882static struct des_fb des_fb[2];
1883
1884struct des3_stinfo {
1885    Block               str_output;
1886    Block               str_feed;
1887    Block               str_iv;
1888    Block               str_ikey[3];
1889    Schedule            str_sched[3];
1890    int                 str_index;
1891    int                 str_flagshift;
1892};
1893
1894struct des3_fb {
1895#ifndef MIT_CURRENT
1896    Block krbdes_key[3];
1897    Schedule krbdes_sched[3];
1898#endif /* MIT_CURRENT */
1899    Block temp_feed;
1900    unsigned char fb_feed[64];
1901    int need_start;
1902    int state[2];
1903    int keyid[2];
1904    int once;
1905#ifdef MIT_CURRENT
1906    int validkey;
1907#endif /* MIT_CURRENT */
1908    struct des3_stinfo streams[2];
1909};
1910static struct des3_fb des3_fb[2];
1911
1912struct keyidlist {
1913    char        *keyid;
1914    int keyidlen;
1915    char        *key;
1916    int keylen;
1917    int flags;
1918} keyidlist [] = {
1919    { "\0", 1, 0, 0, 0 },               /* default key of zero */
1920    { 0, 0, 0, 0, 0 }
1921};
1922
1923#define KEYFLAG_MASK    03
1924
1925#define KEYFLAG_NOINIT  00
1926#define KEYFLAG_INIT    01
1927#define KEYFLAG_OK      02
1928#define KEYFLAG_BAD     03
1929
1930#define KEYFLAG_SHIFT   2
1931
1932#define SHIFT_VAL(a,b)  (KEYFLAG_SHIFT*((a)+((b)*2)))
1933
1934#define FB64_IV         1
1935#define FB64_IV_OK      2
1936#define FB64_IV_BAD     3
1937#define FB64_CHALLENGE  4
1938#define FB64_RESPONSE   5
1939
1940void fb64_stream_iv P((Block, struct des_stinfo *));
1941void fb64_init P((struct des_fb *));
1942static int fb64_start P((struct des_fb *, int, int));
1943int fb64_is P((unsigned char *, int, struct des_fb *));
1944int fb64_reply P((unsigned char *, int, struct des_fb *));
1945static int fb64_session P((Session_Key *, int, struct des_fb *));
1946void fb64_stream_key P((Block, struct des_stinfo *));
1947int fb64_keyid P((int, unsigned char *, int *, struct des_fb *));
1948
1949#ifdef MIT_CURRENT
1950static void
1951#ifdef CK_ANSIC
1952ecb_encrypt(struct des_stinfo *stp, Block in, Block out)
1953#else /* CKANSIC */
1954ecb_encrypt(stp, in, out)
1955    struct des_stinfo *stp;
1956    Block in;
1957    Block out;
1958#endif /* CK_ANSIC */
1959{
1960    krb5_error_code code;
1961    krb5_data din;
1962    krb5_enc_data dout;
1963
1964    din.length = 8;
1965    din.data = in;
1966
1967    dout.ciphertext.length = 8;
1968    dout.ciphertext.data = out;
1969    dout.enctype = ENCTYPE_UNKNOWN;
1970
1971#ifdef CRYPT_DLL
1972    code = krb5_c_encrypt(*p_k5_context, &stp->str_key, 0, 0,
1973                           &din, &dout);
1974#else /* CRYPT_DLL */
1975    code = krb5_c_encrypt(k5_context, &stp->str_key, 0, 0,
1976                           &din, &dout);
1977#endif /* CRYPT_DLL */
1978    /* XXX I'm not sure what to do if this fails */
1979    if (code)
1980        com_err("libtelnet", code, "encrypting stream data");
1981}
1982#endif /* MIT_CURRENT */
1983
1984void
1985cfb64_init(server)
1986    int server;
1987{
1988    fb64_init(&des_fb[CFB]);
1989    des_fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64;
1990    des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
1991    des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
1992}
1993
1994void
1995ofb64_init(server)
1996    int server;
1997{
1998    fb64_init(&des_fb[OFB]);
1999    des_fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64;
2000    des_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
2001    des_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
2002}
2003
2004void
2005fb64_init(fbp)
2006    register struct des_fb *fbp;
2007{
2008    memset((void *)fbp, 0, sizeof(*fbp));
2009    fbp->state[0] = fbp->state[1] = xFAILED;
2010    fbp->fb_feed[0] = IAC;
2011    fbp->fb_feed[1] = SB;
2012    fbp->fb_feed[2] = TELOPT_ENCRYPTION;
2013    fbp->fb_feed[3] = ENCRYPT_IS;
2014}
2015
2016/*
2017 * Returns:
2018 *      -1: some error.  Negotiation is done, encryption not ready.
2019 *       0: Successful, initial negotiation all done.
2020 *       1: successful, negotiation not done yet.
2021 *       2: Not yet.  Other things (like getting the key from
2022 *          Kerberos) have to happen before we can continue.
2023 */
2024int
2025cfb64_start(dir, server)
2026    int dir;
2027    int server;
2028{
2029    return(fb64_start(&des_fb[CFB], dir, server));
2030}
2031int
2032ofb64_start(dir, server)
2033    int dir;
2034    int server;
2035{
2036    return(fb64_start(&des_fb[OFB], dir, server));
2037}
2038
2039static int
2040fb64_start(fbp, dir, server)
2041    struct des_fb *fbp;
2042    int dir;
2043    int server;
2044{
2045    int x;
2046    unsigned char *p;
2047    register int state;
2048
2049    switch (dir) {
2050    case DIR_DECRYPT:
2051        /*
2052        * This is simply a request to have the other side
2053        * start output (our input).  He will negotiate an
2054        * IV so we need not look for it.
2055        */
2056        state = fbp->state[dir-1];
2057        if (state == xFAILED)
2058            state = IN_PROGRESS;
2059        break;
2060
2061    case DIR_ENCRYPT:
2062        state = fbp->state[dir-1];
2063        if (state == xFAILED)
2064            state = IN_PROGRESS;
2065        else if ((state & NO_SEND_IV) == 0)
2066            break;
2067
2068#ifdef MIT_CURRENT
2069        if (!fbp->validkey) {
2070            fbp->need_start = 1;
2071            break;
2072        }
2073#else /* MIT_CURRENT */
2074        if (!VALIDKEY(fbp->krbdes_key)) {
2075            fbp->need_start = 1;
2076            break;
2077        }
2078#endif /* MIT_CURRENT */
2079        state &= ~NO_SEND_IV;
2080        state |= NO_RECV_IV;
2081        /*
2082        * Create a random feed and send it over.
2083        */
2084#ifdef MIT_CURRENT
2085        {
2086            krb5_data d;
2087            krb5_error_code code;
2088
2089            d.data = fbp->temp_feed;
2090            d.length = sizeof(fbp->temp_feed);
2091
2092#ifdef CRYPT_DLL
2093            if (code = krb5_c_random_make_octets(*p_k5_context,&d))
2094                return(xFAILED);
2095#else /* CRYPT_DLL */
2096            if (code = krb5_c_random_make_octets(k5_context,&d))
2097                return(xFAILED);
2098#endif /* CRYPT_DLL */
2099        }
2100
2101#else /* MIT_CURRENT */
2102        des_new_random_key(fbp->temp_feed);
2103        des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
2104                         fbp->krbdes_sched, 1);
2105#endif /* MIT_CURRENT */
2106        p = fbp->fb_feed + 3;
2107        *p++ = ENCRYPT_IS;
2108        p++;
2109        *p++ = FB64_IV;
2110        for (x = 0; x < sizeof(Block); ++x) {
2111            if (( *p++ = fbp->temp_feed[x]) == IAC)
2112                *p++ = IAC;
2113        }
2114        *p++ = IAC;
2115        *p++ = SE;
2116
2117        if (deblog || tn_deb || debses) {
2118            int i;
2119            sprintf(tn_msg,
2120                     "TELNET SENT SB %s IS %s FB64_IV ",
2121                     TELOPT(fbp->fb_feed[2]),
2122                     enctype_names[fbp->fb_feed[4]]);                   /* safe */
2123            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
2124            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
2125            debug(F100,tn_msg,"",0);
2126            if (tn_deb || debses) tn_debug(tn_msg);
2127        }
2128#ifdef OS2
2129        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
2130#endif
2131        ttol(fbp->fb_feed, p - fbp->fb_feed);
2132#ifdef OS2
2133        ReleaseTelnetMutex();
2134#endif
2135        break;
2136    default:
2137        return(xFAILED);
2138    }
2139    return(fbp->state[dir-1] = state);
2140}
2141
2142/*
2143 * Returns:
2144 *      -1: some error.  Negotiation is done, encryption not ready.
2145 *       0: Successful, initial negotiation all done.
2146 *       1: successful, negotiation not done yet.
2147 */
2148int
2149cfb64_is(data, cnt)
2150    unsigned char *data;
2151    int cnt;
2152{
2153    return(fb64_is(data, cnt, &des_fb[CFB]));
2154}
2155
2156int
2157ofb64_is(data, cnt)
2158    unsigned char *data;
2159    int cnt;
2160{
2161    return(fb64_is(data, cnt, &des_fb[OFB]));
2162}
2163
2164int
2165fb64_is(data, cnt, fbp)
2166    unsigned char *data;
2167    int cnt;
2168    struct des_fb *fbp;
2169{
2170    unsigned char *p;
2171    register int state = fbp->state[DIR_DECRYPT-1];
2172
2173    if (cnt-- < 1)
2174        goto failure;
2175
2176#ifdef CK_SSL
2177    if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
2178#endif /* CK_SSL */
2179    switch (*data++) {
2180    case FB64_IV:
2181        if (cnt != sizeof(Block)) {
2182#ifdef DEBUG
2183            if (encrypt_debug_mode)
2184                printf("CFB64: initial vector failed on size\r\n");
2185#endif
2186            state = xFAILED;
2187            goto failure;
2188        }
2189
2190#ifdef DEBUG
2191        if (encrypt_debug_mode) {
2192            printf("CFB64: initial vector received\r\n");
2193            printf("Initializing Decrypt stream\r\n");
2194        }
2195#endif
2196        fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
2197
2198        p = fbp->fb_feed + 3;
2199        *p++ = ENCRYPT_REPLY;
2200        p++;
2201        *p++ = FB64_IV_OK;
2202        *p++ = IAC;
2203        *p++ = SE;
2204
2205        if (deblog || tn_deb || debses) {
2206            int i;
2207            sprintf(tn_msg,
2208                     "TELNET SENT SB %s REPLY %s FB64_IV_OK ",
2209                     TELOPT(fbp->fb_feed[2]),
2210                     enctype_names[fbp->fb_feed[4]]);           /* safe */
2211            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
2212            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
2213            debug(F100,tn_msg,"",0);
2214            if (tn_deb || debses) tn_debug(tn_msg);
2215        }
2216#ifdef OS2
2217        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
2218#endif
2219        ttol(fbp->fb_feed, p - fbp->fb_feed);
2220#ifdef OS2
2221        ReleaseTelnetMutex();
2222#endif
2223        state = IN_PROGRESS;
2224        break;
2225
2226    default:
2227#if 0
2228        if (encrypt_debug_mode) {
2229            printf("Unknown option type: %d\r\n", *(data-1));
2230            printf("\r\n");
2231        }
2232#endif
2233        /* FALL THROUGH */
2234      failure:
2235        /*
2236        * We failed.  Send an FB64_IV_BAD option
2237        * to the other side so it will know that
2238        * things failed.
2239        */
2240        p = fbp->fb_feed + 3;
2241        *p++ = ENCRYPT_REPLY;
2242        p++;
2243        *p++ = FB64_IV_BAD;
2244        *p++ = IAC;
2245        *p++ = SE;
2246
2247        if (deblog || tn_deb || debses) {
2248            int i;
2249            sprintf(tn_msg,
2250                     "TELNET SENT SB %s REPLY %s FB64_IV_BAD ",
2251                     TELOPT(fbp->fb_feed[2]),
2252                     enctype_names[fbp->fb_feed[4]]);           /* safe */
2253            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
2254            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
2255            debug(F100,tn_msg,"",0);
2256            if (tn_deb || debses) tn_debug(tn_msg);
2257        }
2258#ifdef OS2
2259        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
2260#endif
2261        ttol(fbp->fb_feed, p - fbp->fb_feed);
2262#ifdef OS2
2263        ReleaseTelnetMutex();
2264#endif
2265        break;
2266    }
2267    return(fbp->state[DIR_DECRYPT-1] = state);
2268}
2269
2270/*
2271 * Returns:
2272 *      -1: some error.  Negotiation is done, encryption not ready.
2273 *       0: Successful, initial negotiation all done.
2274 *       1: successful, negotiation not done yet.
2275 */
2276int
2277cfb64_reply(data, cnt)
2278    unsigned char *data;
2279    int cnt;
2280{
2281    return(fb64_reply(data, cnt, &des_fb[CFB]));
2282}
2283int
2284ofb64_reply(data, cnt)
2285    unsigned char *data;
2286    int cnt;
2287{
2288    return(fb64_reply(data, cnt, &des_fb[OFB]));
2289}
2290
2291
2292int
2293fb64_reply(data, cnt, fbp)
2294    unsigned char *data;
2295    int cnt;
2296    struct des_fb *fbp;
2297{
2298    register int state = fbp->state[DIR_ENCRYPT-1];
2299
2300    if (cnt-- < 1)
2301        goto failure;
2302
2303    switch (*data++) {
2304    case FB64_IV_OK:
2305        fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
2306        if (state == xFAILED)
2307            state = IN_PROGRESS;
2308        state &= ~NO_RECV_IV;
2309        encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
2310        break;
2311
2312    case FB64_IV_BAD:
2313        memset(fbp->temp_feed, 0, sizeof(Block));
2314        fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
2315        state = xFAILED;
2316        break;
2317
2318    default:
2319#if 0
2320        if (encrypt_debug_mode) {
2321            printf("Unknown option type: %d\r\n", data[-1]);
2322            printf("\r\n");
2323        }
2324#endif
2325        /* FALL THROUGH */
2326      failure:
2327        state = xFAILED;
2328        break;
2329    }
2330    return(fbp->state[DIR_ENCRYPT-1] = state);
2331}
2332
2333int
2334cfb64_session(key, server)
2335    Session_Key *key;
2336    int server;
2337{
2338    return(fb64_session(key, server, &des_fb[CFB]));
2339}
2340
2341int
2342ofb64_session(key, server)
2343    Session_Key *key;
2344    int server;
2345{
2346    return(fb64_session(key, server, &des_fb[OFB]));
2347}
2348
2349static int
2350fb64_session(key, server, fbp)
2351    Session_Key *key;
2352    int server;
2353    struct des_fb *fbp;
2354{
2355    int rc=0;
2356    int use2keys;
2357    struct des_stinfo * s_stream;
2358    struct des_stinfo * c_stream;
2359
2360    if(server) {
2361        s_stream = &fbp->streams[DIR_ENCRYPT-1];
2362        c_stream = &fbp->streams[DIR_DECRYPT-1];
2363    }
2364    else {
2365        s_stream = &fbp->streams[DIR_DECRYPT-1];
2366        c_stream = &fbp->streams[DIR_ENCRYPT-1];
2367    }
2368
2369    if (!key || key->length < sizeof(Block)) {
2370        CHAR buf[80];
2371        sprintf(buf,"Can't set DES session key (%d < %d)",
2372                key ? key->length : 0, sizeof(Block));          /* safe */
2373#ifdef DEBUG
2374        if (encrypt_debug_mode)
2375            printf("%s\r\n",buf);
2376#endif
2377        debug(F110,"fb64_session",buf,0);
2378        return(-1);
2379    }
2380    use2keys = (key->type == SK_DES ||
2381                 key->length < 2 * sizeof(Block)) ? 0 : 1;
2382#ifdef MIT_CURRENT
2383    if(use2keys) {
2384        memcpy((void *) fbp->keybytes,
2385                 (void *) (key->data + sizeof(Block)), sizeof(Block));
2386        des_fixup_key_parity(fbp->);
2387        fb64_stream_key(fbp->krbdes_key, s_stream);
2388    }
2389
2390    memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
2391    if (key->type != SK_DES)
2392        des_fixup_key_parity(fbp->krbdes_key);
2393
2394    if(!use2keys)
2395        fb64_stream_key(fbp->krbdes_key, s_stream);
2396    fb64_stream_key(fbp->krbdes_key, c_stream);
2397    fbp->validkey = 1;
2398
2399    fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1]);
2400    fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1]);
2401#else /* MIT_CURRENT */
2402    if(use2keys) {
2403        memcpy((void *) fbp->krbdes_key,
2404                 (void *) (key->data + sizeof(Block)), sizeof(Block));
2405        des_fixup_key_parity(fbp->krbdes_key);
2406        fb64_stream_key(fbp->krbdes_key, s_stream);
2407    }
2408
2409    memcpy((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block));
2410    if (key->type != SK_DES)
2411        des_fixup_key_parity(fbp->krbdes_key);
2412
2413    if(!use2keys)
2414        fb64_stream_key(fbp->krbdes_key, s_stream);
2415    fb64_stream_key(fbp->krbdes_key, c_stream);
2416
2417    if (fbp->once == 0) {
2418        des_set_random_generator_seed(fbp->krbdes_key);
2419        fbp->once = 1;
2420    }
2421
2422    memset(fbp->krbdes_sched,0,sizeof(Schedule));
2423    hexdump("fb64_session_key",fbp->krbdes_key,8);
2424
2425    rc = des_key_sched(fbp->krbdes_key, fbp->krbdes_sched);
2426    if ( rc == -1 ) {
2427        printf("?Invalid DES key specified for encryption\n");
2428        debug(F110,"fb64_session_key",
2429               "invalid DES Key specified for encryption",0);
2430    } else if ( rc == -2 ) {
2431        printf("?Weak DES key specified for encryption\n");
2432        debug(F110,"fb64_session_key",
2433               "weak DES Key specified for encryption",0);
2434    } else if ( rc != 0 ) {
2435        printf("?Key Schedule not created by encryption\n");
2436        debug(F110,"fb64_session_key",
2437               "Key Schedule not created by encryption",0);
2438    }
2439
2440    hexdump("fb64_session_key schedule",fbp->krbdes_sched,8*16);
2441#endif /* MIT_CURRENT */
2442    /*
2443    * Now look to see if krbdes_start() was was waiting for
2444    * the key to show up.  If so, go ahead an call it now
2445    * that we have the key.
2446    */
2447    if (fbp->need_start) {
2448        fbp->need_start = 0;
2449        fb64_start(fbp, DIR_ENCRYPT, server);
2450    }
2451    return(0);
2452}
2453
2454/*
2455 * We only accept a keyid of 0.  If we get a keyid of
2456 * 0, then mark the state as SUCCESS.
2457 */
2458int
2459cfb64_keyid(dir, kp, lenp)
2460    int dir, *lenp;
2461    unsigned char *kp;
2462{
2463    return(fb64_keyid(dir, kp, lenp, &des_fb[CFB]));
2464}
2465
2466int
2467ofb64_keyid(dir, kp, lenp)
2468    int dir, *lenp;
2469    unsigned char *kp;
2470{
2471    return(fb64_keyid(dir, kp, lenp, &des_fb[OFB]));
2472}
2473
2474int
2475fb64_keyid(dir, kp, lenp, fbp)
2476    int dir, *lenp;
2477    unsigned char *kp;
2478    struct des_fb *fbp;
2479{
2480    register int state = fbp->state[dir-1];
2481
2482    if (*lenp != 1 || (*kp != '\0')) {
2483        *lenp = 0;
2484        return(state);
2485    }
2486
2487    if (state == xFAILED)
2488        state = IN_PROGRESS;
2489
2490    state &= ~NO_KEYID;
2491
2492    return(fbp->state[dir-1] = state);
2493}
2494
2495#if 0
2496void
2497fb64_printsub(data, cnt, buf, buflen, type)
2498    unsigned char *data, *buf, *type;
2499    int cnt, buflen;
2500{
2501    char lbuf[64];
2502    register int i;
2503    char *cp;
2504
2505    buf[buflen-1] = '\0';               /* make sure it's NULL terminated */
2506    buflen -= 1;
2507
2508    switch(data[2]) {
2509    case FB64_IV:
2510        sprintf(lbuf, "%s_IV", type);
2511        cp = lbuf;
2512        goto common;
2513
2514    case FB64_IV_OK:
2515        sprintf(lbuf, "%s_IV_OK", type);
2516        cp = lbuf;
2517        goto common;
2518
2519    case FB64_IV_BAD:
2520        sprintf(lbuf, "%s_IV_BAD", type);
2521        cp = lbuf;
2522        goto common;
2523
2524    case FB64_CHALLENGE:
2525        sprintf(lbuf, "%s_CHALLENGE", type);
2526        cp = lbuf;
2527        goto common;
2528
2529    case FB64_RESPONSE:
2530        sprintf(lbuf, "%s_RESPONSE", type);
2531        cp = lbuf;
2532        goto common;
2533
2534    default:
2535        sprintf(lbuf, " %d (unknown)", data[2]);
2536        cp = lbuf;
2537      common:
2538        for (; (buflen > 0) && (*buf = *cp++); buf++)
2539            buflen--;
2540        for (i = 3; i < cnt; i++) {
2541            sprintf(lbuf, " %d", data[i]);
2542            for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
2543                buflen--;
2544        }
2545        break;
2546    }
2547}
2548
2549void
2550cfb64_printsub(data, cnt, buf, buflen)
2551    unsigned char *data, *buf;
2552    int cnt, buflen;
2553{
2554    fb64_printsub(data, cnt, buf, buflen, "CFB64");
2555}
2556
2557void
2558ofb64_printsub(data, cnt, buf, buflen)
2559    unsigned char *data, *buf;
2560    int cnt, buflen;
2561{
2562    fb64_printsub(data, cnt, buf, buflen, "OFB64");
2563}
2564#endif
2565
2566void
2567fb64_stream_iv(seed, stp)
2568    Block seed;
2569    register struct des_stinfo *stp;
2570{
2571    int rc=0;
2572
2573    memcpy(stp->str_iv,     seed, sizeof(Block));
2574    memcpy(stp->str_output, seed, sizeof(Block));
2575
2576    memset(stp->str_sched,0,sizeof(Schedule));
2577
2578    hexdump("fb64_stream_iv",stp->str_ikey,8);
2579
2580#ifndef MIT_CURRENT
2581    rc = des_key_sched(stp->str_ikey, stp->str_sched);
2582    if ( rc == -1 ) {
2583        printf("?Invalid DES key specified for encryption\r\n");
2584        debug(F110,"fb64_stream_iv",
2585               "invalid DES Key specified for encryption",0);
2586    } else if ( rc == -2 ) {
2587        printf("?Weak DES key specified for encryption\r\n");
2588        debug(F110,"fb64_stream_iv",
2589               "weak DES Key specified for encryption",0);
2590    } else if ( rc != 0 ) {
2591        printf("?Key Schedule not created by encryption\r\n");
2592        debug(F110,"fb64_stream_iv",
2593               "Key Schedule not created by encryption",0);
2594    }
2595    hexdump("fb64_stream_iv schedule",stp->str_sched,8*16);
2596#endif /* MIT_CURRENT */
2597
2598    stp->str_index = sizeof(Block);
2599}
2600
2601void
2602fb64_stream_key(key, stp)
2603    Block key;
2604    register struct des_stinfo *stp;
2605{
2606    int rc = 0;
2607
2608#ifdef MIT_CURRENT
2609    memcpy(stp->str_keybytes, key, sizeof(Block));
2610    stp->str_key.length = 8;
2611    stp->str_key.contents = stp->str_keybytes;
2612    /* the original version of this code uses des ecb mode, but
2613    it only ever does one block at a time.  cbc with a zero iv
2614    is identical */
2615    stp->str_key.enctype = ENCTYPE_DES_CBC_RAW;
2616#else /* MIT_CURRENT */
2617    memcpy(stp->str_ikey, key, sizeof(Block));
2618
2619    memset(stp->str_sched,0,sizeof(Schedule));
2620
2621    hexdump("fb64_stream_key",key,8);
2622
2623    rc = des_key_sched(key, stp->str_sched);
2624    if ( rc == -1 ) {
2625        printf("?Invalid DES key specified for encryption\r\n");
2626        debug(F110,"fb64_stream_iv",
2627               "invalid DES Key specified for encryption",0);
2628    } else if ( rc == -2 ) {
2629        printf("?Weak DES key specified for encryption\r\n");
2630        debug(F110,"fb64_stream_iv",
2631               "weak DES Key specified for encryption",0);
2632    } else if ( rc != 0 ) {
2633        printf("?Key Schedule not created by encryption\r\n");
2634        debug(F110,"fb64_stream_iv",
2635               "Key Schedule not created by encryption",0);
2636    }
2637    hexdump("fb64_stream_key schedule",stp->str_sched,8*16);
2638#endif /* MIT_CURRENT */
2639
2640    memcpy(stp->str_output, stp->str_iv, sizeof(Block));
2641
2642    stp->str_index = sizeof(Block);
2643}
2644
2645/*
2646 * DES 64 bit Cipher Feedback
2647 *
2648 *     key --->+-----+
2649 *          +->| DES |--+
2650 *          |  +-----+  |
2651 *          |           v
2652 *  INPUT --(--------->(+)+---> DATA
2653 *          |             |
2654 *          +-------------+
2655 *
2656 *
2657 * Given:
2658 *      iV: Initial vector, 64 bits (8 bytes) long.
2659 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
2660 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
2661 *
2662 *      V0 = DES(iV, key)
2663 *      On = Dn ^ Vn
2664 *      V(n+1) = DES(On, key)
2665 */
2666
2667void
2668cfb64_encrypt(s, c)
2669    register unsigned char *s;
2670    int c;
2671{
2672    register struct des_stinfo *stp = &des_fb[CFB].streams[DIR_ENCRYPT-1];
2673    register int index;
2674
2675    index = stp->str_index;
2676    while (c-- > 0) {
2677        if (index == sizeof(Block)) {
2678            Block b;
2679#ifdef MIT_CURRENT
2680            ecb_encrypt(stp, stp->str_output, b);
2681#else /* MIT_CURRENT */
2682            des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
2683#endif /* MIT_CURRENT */
2684            memcpy(stp->str_feed,b,sizeof(Block));
2685            index = 0;
2686        }
2687
2688        /* On encryption, we store (feed ^ data) which is cypher */
2689        *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
2690        s++;
2691        index++;
2692    }
2693    stp->str_index = index;
2694}
2695
2696int
2697cfb64_decrypt(data)
2698    int data;
2699{
2700    register struct des_stinfo *stp = &des_fb[CFB].streams[DIR_DECRYPT-1];
2701    int index;
2702
2703    if (data == -1) {
2704        /*
2705        * Back up one byte.  It is assumed that we will
2706        * never back up more than one byte.  If we do, this
2707        * may or may not work.
2708        */
2709        if (stp->str_index)
2710            --stp->str_index;
2711        return(0);
2712    }
2713
2714    index = stp->str_index++;
2715    if (index == sizeof(Block)) {
2716        Block b;
2717#ifdef MIT_CURRENT
2718        ecb_encrypt(stp, stp->str_output, b);
2719#else /* MIT_CURRENT */
2720        des_ecb_encrypt(stp->str_output, b, stp->str_sched, 1);
2721#endif /* MIT_CURRENT */
2722        memcpy(stp->str_feed, b, sizeof(Block));
2723        stp->str_index = 1;     /* Next time will be 1 */
2724        index = 0;              /* But now use 0 */
2725    }
2726
2727    /* On decryption we store (data) which is cypher. */
2728    stp->str_output[index] = data;
2729    return(data ^ stp->str_feed[index]);
2730}
2731
2732/*
2733 * DES 64 bit Output Feedback
2734 *
2735 * key --->+-----+
2736 *      +->| DES |--+
2737 *      |  +-----+  |
2738 *      +-----------+
2739 *                  v
2740 *  INPUT -------->(+) ----> DATA
2741 *
2742 * Given:
2743 *      iV: Initial vector, 64 bits (8 bytes) long.
2744 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
2745 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
2746 *
2747 *      V0 = DES(iV, key)
2748 *      V(n+1) = DES(Vn, key)
2749 *      On = Dn ^ Vn
2750 */
2751void
2752ofb64_encrypt(s, c)
2753    register unsigned char *s;
2754    int c;
2755{
2756    register struct des_stinfo *stp = &des_fb[OFB].streams[DIR_ENCRYPT-1];
2757    register int index;
2758
2759    index = stp->str_index;
2760    while (c-- > 0) {
2761        if (index == sizeof(Block)) {
2762            Block b;
2763#ifdef MIT_CURRENT
2764            ecb_encrypt(stp, stp->str_feed, b);
2765#else /* MIT_CURRENT */
2766            des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
2767#endif /* MIT_CURRENT */
2768            memcpy(stp->str_feed,b,sizeof(Block));
2769            index = 0;
2770        }
2771        *s++ ^= stp->str_feed[index];
2772        index++;
2773    }
2774    stp->str_index = index;
2775}
2776
2777int
2778ofb64_decrypt(data)
2779    int data;
2780{
2781    register struct des_stinfo *stp = &des_fb[OFB].streams[DIR_DECRYPT-1];
2782    int index;
2783
2784    if (data == -1) {
2785        /*
2786        * Back up one byte.  It is assumed that we will
2787        * never back up more than one byte.  If we do, this
2788        * may or may not work.
2789        */
2790        if (stp->str_index)
2791            --stp->str_index;
2792        return(0);
2793    }
2794
2795    index = stp->str_index++;
2796    if (index == sizeof(Block)) {
2797        Block b;
2798#ifdef MIT_CURRENT
2799        ecb_encrypt(stp, stp->str_feed, b);
2800#else /* MIT_CURRENT */
2801        des_ecb_encrypt(stp->str_feed, b, stp->str_sched, 1);
2802#endif /* MIT_CURRENT */
2803        memcpy(stp->str_feed, b, sizeof(Block));
2804        stp->str_index = 1;     /* Next time will be 1 */
2805        index = 0;              /* But now use 0 */
2806    }
2807
2808    return(data ^ stp->str_feed[index]);
2809}
2810
2811
2812void des3_fb64_stream_iv P((Block, struct des3_stinfo *));
2813void des3_fb64_init P((struct des3_fb *));
2814static int des3_fb64_start P((struct des3_fb *, int, int));
2815int des3_fb64_is P((unsigned char *, int, struct des3_fb *));
2816int des3_fb64_reply P((unsigned char *, int, struct des3_fb *));
2817static int des3_fb64_session P((Session_Key *, int, struct des3_fb *));
2818void des3_fb64_stream_key P((Block *, struct des3_stinfo *));
2819int des3_fb64_keyid P((int, unsigned char *, int *, struct des3_fb *));
2820
2821void
2822des3_cfb64_init(server)
2823    int server;
2824{
2825    des3_fb64_init(&des3_fb[CFB]);
2826    des3_fb[CFB].fb_feed[4] = ENCTYPE_DES3_CFB64;
2827    des3_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB);
2828    des3_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB);
2829}
2830
2831void
2832des3_ofb64_init(server)
2833    int server;
2834{
2835    des3_fb64_init(&des3_fb[OFB]);
2836    des3_fb[OFB].fb_feed[4] = ENCTYPE_DES3_OFB64;
2837    des3_fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB);
2838    des3_fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB);
2839}
2840
2841void
2842des3_fb64_init(fbp)
2843    register struct des3_fb *fbp;
2844{
2845    memset((void *)fbp, 0, sizeof(*fbp));
2846    fbp->state[0] = fbp->state[1] = xFAILED;
2847    fbp->fb_feed[0] = IAC;
2848    fbp->fb_feed[1] = SB;
2849    fbp->fb_feed[2] = TELOPT_ENCRYPTION;
2850    fbp->fb_feed[3] = ENCRYPT_IS;
2851}
2852
2853/*
2854 * Returns:
2855 *      -1: some error.  Negotiation is done, encryption not ready.
2856 *       0: Successful, initial negotiation all done.
2857 *       1: successful, negotiation not done yet.
2858 *       2: Not yet.  Other things (like getting the key from
2859 *          Kerberos) have to happen before we can continue.
2860 */
2861int
2862des3_cfb64_start(dir, server)
2863    int dir;
2864    int server;
2865{
2866    return(des3_fb64_start(&des3_fb[CFB], dir, server));
2867}
2868int
2869des3_ofb64_start(dir, server)
2870    int dir;
2871    int server;
2872{
2873    return(des3_fb64_start(&des3_fb[OFB], dir, server));
2874}
2875
2876static int
2877des3_fb64_start(fbp, dir, server)
2878    struct des3_fb *fbp;
2879    int dir;
2880    int server;
2881{
2882    int x;
2883    unsigned char *p;
2884    register int state;
2885
2886    switch (dir) {
2887    case DIR_DECRYPT:
2888        /*
2889        * This is simply a request to have the other side
2890        * start output (our input).  He will negotiate an
2891        * IV so we need not look for it.
2892        */
2893        state = fbp->state[dir-1];
2894        if (state == xFAILED)
2895            state = IN_PROGRESS;
2896        break;
2897
2898    case DIR_ENCRYPT:
2899        state = fbp->state[dir-1];
2900        if (state == xFAILED)
2901            state = IN_PROGRESS;
2902        else if ((state & NO_SEND_IV) == 0)
2903            break;
2904
2905        if (!VALIDKEY(fbp->krbdes_key[0]) ||
2906            !VALIDKEY(fbp->krbdes_key[1]) ||
2907            !VALIDKEY(fbp->krbdes_key[2]) ) {
2908            fbp->need_start = 1;
2909            break;
2910        }
2911        state &= ~NO_SEND_IV;
2912        state |= NO_RECV_IV;
2913        /*
2914        * Create a random feed and send it over.
2915        */
2916        des_new_random_key(fbp->temp_feed);
2917#ifdef LIBDES
2918        des_ecb3_encrypt(fbp->temp_feed, fbp->temp_feed,
2919                         fbp->krbdes_sched[0],
2920                         fbp->krbdes_sched[1],
2921                         fbp->krbdes_sched[2],
2922                         1);
2923#else /* LIBDES */
2924        des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
2925                         fbp->krbdes_sched[0], 1);
2926        des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
2927                         fbp->krbdes_sched[1], 0);
2928        des_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
2929                         fbp->krbdes_sched[2], 1);
2930#endif /* LIBDES */
2931
2932        p = fbp->fb_feed + 3;
2933        *p++ = ENCRYPT_IS;
2934        p++;
2935        *p++ = FB64_IV;
2936        for (x = 0; x < sizeof(Block); ++x) {
2937            if (( *p++ = fbp->temp_feed[x]) == IAC)
2938                *p++ = IAC;
2939        }
2940        *p++ = IAC;
2941        *p++ = SE;
2942
2943        if (deblog || tn_deb || debses) {
2944            int i;
2945            sprintf(tn_msg,
2946                     "TELNET SENT SB %s IS %s FB64_IV ",
2947                     TELOPT(fbp->fb_feed[2]),
2948                     enctype_names[fbp->fb_feed[4]]);           /* safe */
2949            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
2950            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
2951            debug(F100,tn_msg,"",0);
2952            if (tn_deb || debses) tn_debug(tn_msg);
2953        }
2954#ifdef OS2
2955        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
2956#endif
2957        ttol(fbp->fb_feed, p - fbp->fb_feed);
2958#ifdef OS2
2959        ReleaseTelnetMutex();
2960#endif
2961        break;
2962    default:
2963        return(xFAILED);
2964    }
2965    return(fbp->state[dir-1] = state);
2966}
2967
2968/*
2969 * Returns:
2970 *      -1: some error.  Negotiation is done, encryption not ready.
2971 *       0: Successful, initial negotiation all done.
2972 *       1: successful, negotiation not done yet.
2973 */
2974int
2975des3_cfb64_is(data, cnt)
2976    unsigned char *data;
2977    int cnt;
2978{
2979    return(des3_fb64_is(data, cnt, &des3_fb[CFB]));
2980}
2981
2982int
2983des3_ofb64_is(data, cnt)
2984    unsigned char *data;
2985    int cnt;
2986{
2987    return(des3_fb64_is(data, cnt, &des3_fb[OFB]));
2988}
2989
2990int
2991des3_fb64_is(data, cnt, fbp)
2992    unsigned char *data;
2993    int cnt;
2994    struct des3_fb *fbp;
2995{
2996    unsigned char *p;
2997    register int state = fbp->state[DIR_DECRYPT-1];
2998
2999    if (cnt-- < 1)
3000        goto failure;
3001
3002#ifdef CK_SSL
3003    if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
3004#endif /* CK_SSL */
3005    switch (*data++) {
3006    case FB64_IV:
3007        if (cnt != sizeof(Block)) {
3008#ifdef DEBUG
3009            if (encrypt_debug_mode)
3010                printf("DES3_FB64: initial vector failed on size\r\n");
3011#endif
3012            state = xFAILED;
3013            goto failure;
3014        }
3015
3016#ifdef DEBUG
3017        if (encrypt_debug_mode) {
3018            printf("DES3_FB64: initial vector received\r\n");
3019            printf("Initializing Decrypt stream\r\n");
3020        }
3021#endif
3022        des3_fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
3023
3024        p = fbp->fb_feed + 3;
3025        *p++ = ENCRYPT_REPLY;
3026        p++;
3027        *p++ = FB64_IV_OK;
3028        *p++ = IAC;
3029        *p++ = SE;
3030
3031        if (deblog || tn_deb || debses) {
3032            int i;
3033            sprintf(tn_msg,
3034                     "TELNET SENT SB %s REPLY %s FB64_IV_OK ",
3035                     TELOPT(fbp->fb_feed[2]),
3036                     enctype_names[fbp->fb_feed[4]]);           /* safe */
3037            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
3038            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
3039            debug(F100,tn_msg,"",0);
3040            if (tn_deb || debses) tn_debug(tn_msg);
3041        }
3042#ifdef OS2
3043        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
3044#endif
3045        ttol(fbp->fb_feed, p - fbp->fb_feed);
3046#ifdef OS2
3047        ReleaseTelnetMutex();
3048#endif
3049        state = IN_PROGRESS;
3050        break;
3051
3052    default:
3053#if 0
3054        if (encrypt_debug_mode) {
3055            printf("Unknown option type: %d\r\n", *(data-1));
3056            printf("\r\n");
3057        }
3058#endif
3059        /* FALL THROUGH */
3060      failure:
3061        /*
3062        * We failed.  Send an FB64_IV_BAD option
3063        * to the other side so it will know that
3064        * things failed.
3065        */
3066        p = fbp->fb_feed + 3;
3067        *p++ = ENCRYPT_REPLY;
3068        p++;
3069        *p++ = FB64_IV_BAD;
3070        *p++ = IAC;
3071        *p++ = SE;
3072
3073        if (deblog || tn_deb || debses) {
3074            int i;
3075            sprintf(tn_msg,
3076                     "TELNET SENT SB %s REPLY %s FB64_IV_BAD ",
3077                     TELOPT(fbp->fb_feed[2]),
3078                     enctype_names[fbp->fb_feed[4]]);           /* safe */
3079            tn_hex(tn_msg,TN_MSG_LEN,&fbp->fb_feed[6],(p-fbp->fb_feed)-2-6);
3080            ckstrncat(tn_msg,"IAC SE",TN_MSG_LEN);
3081            debug(F100,tn_msg,"",0);
3082            if (tn_deb || debses) tn_debug(tn_msg);
3083        }
3084#ifdef OS2
3085        RequestTelnetMutex( SEM_INDEFINITE_WAIT );
3086#endif
3087        ttol(fbp->fb_feed, p - fbp->fb_feed);
3088#ifdef OS2
3089        ReleaseTelnetMutex();
3090#endif
3091        break;
3092    }
3093    return(fbp->state[DIR_DECRYPT-1] = state);
3094}
3095
3096/*
3097 * Returns:
3098 *      -1: some error.  Negotiation is done, encryption not ready.
3099 *       0: Successful, initial negotiation all done.
3100 *       1: successful, negotiation not done yet.
3101 */
3102int
3103des3_cfb64_reply(data, cnt)
3104    unsigned char *data;
3105    int cnt;
3106{
3107    return(des3_fb64_reply(data, cnt, &des3_fb[CFB]));
3108}
3109int
3110des3_ofb64_reply(data, cnt)
3111    unsigned char *data;
3112    int cnt;
3113{
3114    return(des3_fb64_reply(data, cnt, &des3_fb[OFB]));
3115}
3116
3117
3118int
3119des3_fb64_reply(data, cnt, fbp)
3120    unsigned char *data;
3121    int cnt;
3122    struct des3_fb *fbp;
3123{
3124    register int state = fbp->state[DIR_ENCRYPT-1];
3125
3126    if (cnt-- < 1)
3127        goto failure;
3128
3129    switch (*data++) {
3130    case FB64_IV_OK:
3131        des3_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
3132        if (state == xFAILED)
3133            state = IN_PROGRESS;
3134        state &= ~NO_RECV_IV;
3135        encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
3136        break;
3137
3138    case FB64_IV_BAD:
3139        memset(fbp->temp_feed, 0, sizeof(Block));
3140        des3_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
3141        state = xFAILED;
3142        break;
3143
3144    default:
3145#if 0
3146        if (encrypt_debug_mode) {
3147            printf("Unknown option type: %d\r\n", data[-1]);
3148            printf("\r\n");
3149        }
3150#endif
3151        /* FALL THROUGH */
3152      failure:
3153        state = xFAILED;
3154        break;
3155    }
3156    return(fbp->state[DIR_ENCRYPT-1] = state);
3157}
3158
3159int
3160des3_cfb64_session(key, server)
3161    Session_Key *key;
3162    int server;
3163{
3164    return(des3_fb64_session(key, server, &des3_fb[CFB]));
3165}
3166
3167int
3168des3_ofb64_session(key, server)
3169    Session_Key *key;
3170    int server;
3171{
3172    return(des3_fb64_session(key, server, &des3_fb[OFB]));
3173}
3174
3175static int
3176des3_fb64_session(key, server, fbp)
3177    Session_Key *key;
3178    int server;
3179    struct des3_fb *fbp;
3180{
3181    int rc=0,i=0;
3182    int keys2use=0;
3183    struct des3_stinfo * s_stream;
3184    struct des3_stinfo * c_stream;
3185
3186    if(server) {
3187        s_stream = &fbp->streams[DIR_ENCRYPT-1];
3188        c_stream = &fbp->streams[DIR_DECRYPT-1];
3189    }
3190    else {
3191        s_stream = &fbp->streams[DIR_DECRYPT-1];
3192        c_stream = &fbp->streams[DIR_ENCRYPT-1];
3193    }
3194
3195    keys2use = key->length / sizeof(Block);
3196    if (!key || (key->type == SK_DES) || (keys2use < 2)) {
3197        CHAR buf[80];
3198        sprintf(buf,"Can't set 3DES session key (%d < %d)",
3199                key ? key->length : 0, 2 * sizeof(Block));      /* safe */
3200#ifdef DEBUG
3201        if (encrypt_debug_mode)
3202            printf("%s\r\n",buf);
3203#endif
3204        debug(F110,"des3_fb64_session",buf,0);
3205        return(-1);
3206    }
3207
3208    debug(F111,"des3_fb64_session","keys2use",keys2use);
3209    /* Compute the first set of keys / key order */
3210    switch ( keys2use ) {
3211    case 2:
3212        memcpy((void *)fbp->krbdes_key[0], (void *)key->data, sizeof(Block));
3213        memcpy((void *) fbp->krbdes_key[1],(void *)(key->data + sizeof(Block)),
3214                 sizeof(Block));
3215        memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
3216        break;
3217    case 3:
3218    default:
3219        memcpy((void *)fbp->krbdes_key[0], (void *)key->data, sizeof(Block));
3220        memcpy((void *) fbp->krbdes_key[1],(void *)(key->data + sizeof(Block)),
3221                 sizeof(Block));
3222        memcpy((void *) fbp->krbdes_key[2],
3223                 (void *) (key->data + 2*sizeof(Block)), sizeof(Block));
3224        break;
3225    }
3226    hexdump("des3_session_key key->data",key->data,sizeof(Block));
3227    hexdump("des3_session_key fbp->krbdes_key[0]",
3228            fbp->krbdes_key[0],
3229            sizeof(Block)
3230            );
3231    if (fbp->once == 0) {
3232        des_set_random_generator_seed(fbp->krbdes_key[0]);
3233        fbp->once = 1;
3234    }
3235
3236    for ( i=0;i<3;i++ )
3237        des_fixup_key_parity(fbp->krbdes_key[i]);
3238    des3_fb64_stream_key(fbp->krbdes_key, s_stream);
3239
3240
3241    /* Compute the second set of keys / key order */
3242    switch ( keys2use ) {
3243    case 2:
3244        memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
3245                 sizeof(Block));
3246        memcpy((void *)fbp->krbdes_key[1], (void *)key->data, sizeof(Block));
3247        memcpy((void *) fbp->krbdes_key[2],(void *)(key->data + sizeof(Block)),
3248                 sizeof(Block));
3249        break;
3250    case 3:
3251        memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
3252                 sizeof(Block));
3253        memcpy((void *) fbp->krbdes_key[1],
3254                 (void *) (key->data + 2*sizeof(Block)), sizeof(Block));
3255        memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
3256        break;
3257    case 4:
3258        memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
3259                 sizeof(Block));
3260        memcpy((void *) fbp->krbdes_key[1],
3261                 (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
3262        memcpy((void *)fbp->krbdes_key[2], (void *)key->data, sizeof(Block));
3263        break;
3264    case 5:
3265        memcpy((void *) fbp->krbdes_key[0],(void *)(key->data + sizeof(Block)),
3266                 sizeof(Block));
3267        memcpy((void *) fbp->krbdes_key[1],
3268                 (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
3269        memcpy((void *)fbp->krbdes_key[2],
3270                 (void *)(key->data + 4*sizeof(Block)), sizeof(Block));
3271        break;
3272    case 6:
3273        memcpy((void *) fbp->krbdes_key[0],
3274                 (void *) (key->data + 3*sizeof(Block)), sizeof(Block));
3275        memcpy((void *)fbp->krbdes_key[1],
3276                 (void *)(key->data + 4*sizeof(Block)), sizeof(Block));
3277        memcpy((void *) fbp->krbdes_key[2],
3278                 (void *) (key->data + 5 *sizeof(Block)),  sizeof(Block));
3279        break;
3280    }
3281
3282    for ( i=0;i<3;i++ )
3283        des_fixup_key_parity(fbp->krbdes_key[i]);
3284    des3_fb64_stream_key(fbp->krbdes_key, c_stream);
3285
3286    /* now use the second set of keys to build the default Key Schedule */
3287    /* which is used for generating the IV.                             */
3288    for ( i=0;i<3;i++ ) {
3289        memset(fbp->krbdes_sched[i],0,sizeof(Schedule));
3290
3291        rc = des_key_sched(fbp->krbdes_key[i], fbp->krbdes_sched[i]);
3292        if ( rc == -1 ) {
3293            printf("?Invalid DES key specified for encryption [DES3,%s]\r\n",
3294                    server?"server":"client");
3295            debug(F110,"des3_fb64_stream_iv",
3296                   "invalid DES Key specified for encryption",0);
3297        } else if ( rc == -2 ) {
3298            printf("?Weak DES key specified for encryption\r\n");
3299            debug(F110,"des3_fb64_stream_iv",
3300                   "weak DES Key specified for encryption",0);
3301        } else if ( rc != 0 ) {
3302            printf("?Key Schedule not created by encryption\r\n");
3303            debug(F110,"des3_fb64_stream_iv",
3304                   "Key Schedule not created by encryption",0);
3305        }
3306        hexdump("des3_fb64_session_key schedule",fbp->krbdes_sched[i],8*16);
3307    }
3308    /*
3309    * Now look to see if krbdes_start() was was waiting for
3310    * the key to show up.  If so, go ahead an call it now
3311    * that we have the key.
3312    */
3313    if (fbp->need_start) {
3314        fbp->need_start = 0;
3315        des3_fb64_start(fbp, DIR_ENCRYPT, server);
3316    }
3317    return(0);
3318}
3319
3320/*
3321 * We only accept a keyid of 0.  If we get a keyid of
3322 * 0, then mark the state as SUCCESS.
3323 */
3324int
3325des3_cfb64_keyid(dir, kp, lenp)
3326    int dir, *lenp;
3327    unsigned char *kp;
3328{
3329    return(des3_fb64_keyid(dir, kp, lenp, &des3_fb[CFB]));
3330}
3331
3332int
3333des3_ofb64_keyid(dir, kp, lenp)
3334    int dir, *lenp;
3335    unsigned char *kp;
3336{
3337    return(des3_fb64_keyid(dir, kp, lenp, &des3_fb[OFB]));
3338}
3339
3340int
3341des3_fb64_keyid(dir, kp, lenp, fbp)
3342    int dir, *lenp;
3343    unsigned char *kp;
3344    struct des3_fb *fbp;
3345{
3346    register int state = fbp->state[dir-1];
3347
3348    if (*lenp != 1 || (*kp != '\0')) {
3349        *lenp = 0;
3350        return(state);
3351    }
3352
3353    if (state == xFAILED)
3354        state = IN_PROGRESS;
3355
3356    state &= ~NO_KEYID;
3357
3358    return(fbp->state[dir-1] = state);
3359}
3360
3361#if 0
3362void
3363des3_fb64_printsub(data, cnt, buf, buflen, type)
3364    unsigned char *data, *buf, *type;
3365    int cnt, buflen;
3366{
3367    char lbuf[64];
3368    register int i;
3369    char *cp;
3370
3371    buf[buflen-1] = '\0';               /* make sure it's NULL terminated */
3372    buflen -= 1;
3373
3374    switch(data[2]) {
3375    case FB64_IV:
3376        sprintf(lbuf, "%s_IV", type);
3377        cp = lbuf;
3378        goto common;
3379
3380    case FB64_IV_OK:
3381        sprintf(lbuf, "%s_IV_OK", type);
3382        cp = lbuf;
3383        goto common;
3384
3385    case FB64_IV_BAD:
3386        sprintf(lbuf, "%s_IV_BAD", type);
3387        cp = lbuf;
3388        goto common;
3389
3390    case FB64_CHALLENGE:
3391        sprintf(lbuf, "%s_CHALLENGE", type);
3392        cp = lbuf;
3393        goto common;
3394
3395    case FB64_RESPONSE:
3396        sprintf(lbuf, "%s_RESPONSE", type);
3397        cp = lbuf;
3398        goto common;
3399
3400    default:
3401        sprintf(lbuf, " %d (unknown)", data[2]);
3402        cp = lbuf;
3403      common:
3404        for (; (buflen > 0) && (*buf = *cp++); buf++)
3405            buflen--;
3406        for (i = 3; i < cnt; i++) {
3407            sprintf(lbuf, " %d", data[i]);
3408            for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
3409                buflen--;
3410        }
3411        break;
3412    }
3413}
3414
3415void
3416des3_cfb64_printsub(data, cnt, buf, buflen)
3417    unsigned char *data, *buf;
3418    int cnt, buflen;
3419{
3420    des3_fb64_printsub(data, cnt, buf, buflen, "CFB64");
3421}
3422
3423void
3424des3_ofb64_printsub(data, cnt, buf, buflen)
3425    unsigned char *data, *buf;
3426    int cnt, buflen;
3427{
3428    des3_fb64_printsub(data, cnt, buf, buflen, "OFB64");
3429}
3430#endif
3431
3432void
3433des3_fb64_stream_iv(seed, stp)
3434    Block seed;
3435    register struct des3_stinfo *stp;
3436{
3437    int rc=0, i = 0;;
3438
3439    memcpy(stp->str_iv,     seed, sizeof(Block));
3440    memcpy(stp->str_output, seed, sizeof(Block));
3441    for ( i=0;i<3;i++ ) {
3442        memset(stp->str_sched[i],0,sizeof(Schedule));
3443
3444        hexdump("des3_fb64_stream_iv",stp->str_ikey[i],8);
3445
3446        rc = des_key_sched(stp->str_ikey[i], stp->str_sched[i]);
3447        if ( rc == -1 ) {
3448            printf("?Invalid DES key specified for encryption [DES3 iv]\r\n");
3449            debug(F110,"des3_fb64_stream_iv",
3450                   "invalid DES Key specified for encryption",0);
3451        } else if ( rc == -2 ) {
3452            printf("?Weak DES key specified for encryption\r\n");
3453            debug(F110,"des3_fb64_stream_iv",
3454                   "weak DES Key specified for encryption",0);
3455        } else if ( rc != 0 ) {
3456            printf("?Key Schedule not created by encryption\r\n");
3457            debug(F110,"des3_fb64_stream_iv",
3458                   "Key Schedule not created by encryption",0);
3459        }
3460        hexdump("des3_fb64_stream_iv schedule",stp->str_sched[i],8*16);
3461    }
3462    stp->str_index = sizeof(Block);
3463}
3464
3465void
3466des3_fb64_stream_key(key, stp)
3467    Block * key;
3468    register struct des3_stinfo *stp;
3469{
3470    int rc = 0, i = 0;
3471
3472    for ( i=0;i<3;i++ ) {
3473        memcpy(stp->str_ikey[i], key[i], sizeof(Block));
3474
3475        memset(stp->str_sched[i],0,sizeof(Schedule));
3476
3477        hexdump("des3_fb64_stream_key",key[i],8);
3478
3479        rc = des_key_sched(key[i], stp->str_sched[i]);
3480        if ( rc == -1 ) {
3481            printf("?Invalid DES key specified for encryption [DES3 key]\r\n");
3482            debug(F110,"des3_fb64_stream_iv",
3483                   "invalid DES Key specified for encryption",0);
3484        } else if ( rc == -2 ) {
3485            printf("?Weak DES key specified for encryption\r\n");
3486            debug(F110,"des3_fb64_stream_iv",
3487                   "weak DES Key specified for encryption",0);
3488        } else if ( rc != 0 ) {
3489            printf("?Key Schedule not created by encryption\r\n");
3490            debug(F110,"des3_fb64_stream_iv",
3491                   "Key Schedule not created by encryption",0);
3492        }
3493        hexdump("des3_fb64_stream_key schedule",stp->str_sched[i],8*16);
3494    }
3495
3496    memcpy(stp->str_output, stp->str_iv, sizeof(Block));
3497    stp->str_index = sizeof(Block);
3498}
3499
3500/*
3501 * DES3 64 bit Cipher Feedback
3502 *
3503 *                key1       key2       key3
3504 *                 |          |          |
3505 *                 v          v          v
3506 *             +-------+  +-------+  +-------+
3507 *          +->| DES-e |->| DES-d |->| DES-e |-- +
3508 *          |  +-------+  +-------+  +-------+   |
3509 *          |                                    v
3510 *  INPUT --(-------------------------------->(+)+---> DATA
3511 *          |                                    |
3512 *          +------------------------------------+
3513 *
3514 *
3515 * Given:
3516 *      iV: Initial vector, 64 bits (8 bytes) long.
3517 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
3518 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
3519 *
3520 *      V0 = DES-e(DES-d(DES-e(iV, key1),key2),key3)
3521 *      On = Dn ^ Vn
3522 *      V(n+1) = DES-e(DES-d(DES-e(On, key1),key2),key3)
3523 */
3524
3525void
3526des3_cfb64_encrypt(s, c)
3527    register unsigned char *s;
3528    int c;
3529{
3530    register struct des3_stinfo *stp = &des3_fb[CFB].streams[DIR_ENCRYPT-1];
3531    register int index;
3532
3533    index = stp->str_index;
3534    while (c-- > 0) {
3535        if (index == sizeof(Block)) {
3536            Block b;
3537#ifdef LIBDES
3538            des_ecb3_encrypt(stp->str_output, b, stp->str_sched[0],
3539                              stp->str_sched[1], stp->str_sched[2], 1);
3540#else /* LIBDES */
3541            des_ecb_encrypt(stp->str_output, b,
3542                             stp->str_sched[0], 1);
3543            des_ecb_encrypt(stp->str_output, b,
3544                             stp->str_sched[1], 0);
3545            des_ecb_encrypt(stp->str_output, b,
3546                             stp->str_sched[2], 1);
3547#endif /* LIBDES */
3548            memcpy(stp->str_feed,b,sizeof(Block));
3549            index = 0;
3550        }
3551
3552        /* On encryption, we store (feed ^ data) which is cypher */
3553        *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
3554        s++;
3555        index++;
3556    }
3557    stp->str_index = index;
3558}
3559
3560int
3561des3_cfb64_decrypt(data)
3562    int data;
3563{
3564    register struct des3_stinfo *stp = &des3_fb[CFB].streams[DIR_DECRYPT-1];
3565    int index;
3566
3567    if (data == -1) {
3568        /*
3569        * Back up one byte.  It is assumed that we will
3570        * never back up more than one byte.  If we do, this
3571        * may or may not work.
3572        */
3573        if (stp->str_index)
3574            --stp->str_index;
3575        return(0);
3576    }
3577
3578    index = stp->str_index++;
3579    if (index == sizeof(Block)) {
3580        Block b;
3581#ifdef LIBDES
3582        des_ecb3_encrypt(stp->str_output, b, stp->str_sched[0],
3583                          stp->str_sched[1], stp->str_sched[2], 1);
3584#else /* LIBDES */
3585            des_ecb_encrypt(stp->str_output, b,
3586                             stp->str_sched[0], 1);
3587            des_ecb_encrypt(stp->str_output, b,
3588                             stp->str_sched[1], 0);
3589            des_ecb_encrypt(stp->str_output, b,
3590                             stp->str_sched[2], 1);
3591#endif /* LIBDES */
3592        memcpy(stp->str_feed, b, sizeof(Block));
3593        stp->str_index = 1;     /* Next time will be 1 */
3594        index = 0;              /* But now use 0 */
3595    }
3596
3597    /* On decryption we store (data) which is cypher. */
3598    stp->str_output[index] = data;
3599    return(data ^ stp->str_feed[index]);
3600}
3601
3602/*
3603 * DES3 64 bit Output Feedback
3604 *
3605 *
3606 *                key1       key2       key3
3607 *                 |          |          |
3608 *                 v          v          v
3609 *             +-------+  +-------+  +-------+
3610 *          +->| DES-e |->| DES-d |->| DES-e |-- +
3611 *          |  +-------+  +-------+  +-------+   |
3612 *          +------------------------------------+
3613 *                                               v
3614 *  INPUT ------------------------------------->(+) ----> DATA
3615 *
3616 * Given:
3617 *      iV: Initial vector, 64 bits (8 bytes) long.
3618 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
3619 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
3620 *
3621 *      V0 = DES-e(DES-d(DES-e(iV, key1),key2),key3)
3622 *      V(n+1) = DES-e(DES-d(DES-e(Vn, key1),key2),key3)
3623 *      On = Dn ^ Vn
3624 */
3625void
3626des3_ofb64_encrypt(s, c)
3627    register unsigned char *s;
3628    int c;
3629{
3630    register struct des3_stinfo *stp = &des3_fb[OFB].streams[DIR_ENCRYPT-1];
3631    register int index;
3632
3633    index = stp->str_index;
3634    while (c-- > 0) {
3635        if (index == sizeof(Block)) {
3636            Block b;
3637#ifdef LIBDES
3638            des_ecb3_encrypt(stp->str_feed, b, stp->str_sched[0],
3639                             stp->str_sched[1], stp->str_sched[2], 1);
3640#else /* LIBDES */
3641            des_ecb_encrypt(stp->str_output, b,
3642                             stp->str_sched[0], 1);
3643            des_ecb_encrypt(stp->str_output, b,
3644                             stp->str_sched[1], 0);
3645            des_ecb_encrypt(stp->str_output, b,
3646                             stp->str_sched[2], 1);
3647#endif /* LIBDES */
3648            memcpy(stp->str_feed,b,sizeof(Block));
3649            index = 0;
3650        }
3651        *s++ ^= stp->str_feed[index];
3652        index++;
3653    }
3654    stp->str_index = index;
3655}
3656
3657int
3658des3_ofb64_decrypt(data)
3659    int data;
3660{
3661    register struct des3_stinfo *stp = &des3_fb[OFB].streams[DIR_DECRYPT-1];
3662    int index;
3663
3664    if (data == -1) {
3665        /*
3666        * Back up one byte.  It is assumed that we will
3667        * never back up more than one byte.  If we do, this
3668        * may or may not work.
3669        */
3670        if (stp->str_index)
3671            --stp->str_index;
3672        return(0);
3673    }
3674
3675    index = stp->str_index++;
3676    if (index == sizeof(Block)) {
3677        Block b;
3678#ifdef LIBDES
3679        des_ecb3_encrypt(stp->str_feed, b, stp->str_sched[0],
3680                          stp->str_sched[1], stp->str_sched[2], 1);
3681#else /* LIBDES */
3682            des_ecb_encrypt(stp->str_output, b,
3683                             stp->str_sched[0], 1);
3684            des_ecb_encrypt(stp->str_output, b,
3685                             stp->str_sched[1], 0);
3686            des_ecb_encrypt(stp->str_output, b,
3687                             stp->str_sched[2], 1);
3688#endif /* LIBDES */
3689        memcpy(stp->str_feed, b, sizeof(Block));
3690        stp->str_index = 1;     /* Next time will be 1 */
3691        index = 0;              /* But now use 0 */
3692    }
3693
3694    return(data ^ stp->str_feed[index]);
3695}
3696#endif /* CK_DES */
3697
3698#ifdef CK_CAST
3699/*-
3700 * Copyright (c) 1991, 1993
3701 *      The Regents of the University of California.  All rights reserved.
3702 *
3703 * Redistribution and use in source and binary forms, with or without
3704 * modification, are permitted provided that the following conditions
3705 * are met:
3706 * 1. Redistributions of source code must retain the above copyright
3707 *    notice, this list of conditions and the following disclaimer.
3708 * 2. Redistributions in binary form must reproduce the above copyright
3709 *    notice, this list of conditions and the following disclaimer in the
3710 *    documentation and/or other materials provided with the distribution.
3711 * 3. All advertising materials mentioning features or use of this software
3712 *    must display the following acknowledgement:
3713 *      This product includes software developed by the University of
3714 *      California, Berkeley and its contributors.
3715 * 4. Neither the name of the University nor the names of its contributors
3716 *    may be used to endorse or promote products derived from this software
3717 *    without specific prior written permission.
3718 *
3719 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3720 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3721 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3722 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3723 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3724 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3725 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3726 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3727 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3728 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3729 * SUCH DAMAGE.
3730 */
3731
3732/*
3733 * Copyright (c) 1997 Stanford University
3734 *
3735 * Permission to use, copy, modify, distribute, and sell this software and
3736 * its documentation for any purpose is hereby granted without fee, provided
3737 * that the above copyright notices and this permission notice appear in
3738 * all copies of the software and related documentation.
3739 *
3740 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
3741 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
3742 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
3743 *
3744 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
3745 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
3746 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
3747 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
3748 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3749 */
3750
3751#include <stdio.h>
3752#ifdef  __STDC__
3753#include <stdlib.h>
3754#endif
3755
3756/*
3757 * cast.h
3758 * Author: Tom Wu
3759 *
3760 * Type and function declarations for CAST.
3761 */
3762
3763#ifndef _CAST_H_
3764#define _CAST_H_
3765
3766#ifndef P
3767#ifdef __STDC__
3768#define P(x) x
3769#else
3770#define P(x) ()
3771#endif /* __STDC__ */
3772#endif /* P */
3773
3774#ifndef LITTLE_ENDIAN
3775#ifndef BIG_ENDIAN
3776#ifndef WORDS_BIGENDIAN
3777#define LITTLE_ENDIAN 1
3778#endif /* WORDS_BIGENDIAN */
3779#endif /* BIG_ENDIAN */
3780#endif /* LITTLE_ENDIAN */
3781
3782typedef unsigned int uint32;    /* Must be 32 bits */
3783typedef uint32 * uint32p;
3784typedef unsigned char uint8;
3785typedef uint8 * uint8p;
3786
3787typedef struct {
3788  struct CastSubkeyPair {
3789    uint32 Km;
3790    uint32 Kr;
3791  } K[16];
3792  int ksize;
3793} CastKeySched;
3794
3795/*
3796 * cast*_key_sched(schedule, key)
3797 *
3798 * Initializes the CAST key schedule "schedule" according to the given key.
3799 * The different setup routines accept different length keys:
3800 *
3801 *   ck_cast5_40_key_sched: 40-bit/5-byte (12 round) keys
3802 *   ck_cast5_64_key_sched: 64-bit/8-byte (12 round) keys
3803 *   ck_cast5_80_key_sched: 80-bit/10-byte (12 round) keys
3804 *   ck_cast128_key_sched: 128-bit/16-byte (16 round) keys
3805 */
3806
3807extern void ck_cast5_40_key_sched P((CastKeySched *, uint8 *));
3808extern void ck_cast5_64_key_sched P((CastKeySched *, uint8 *));
3809extern void ck_cast5_80_key_sched P((CastKeySched *, uint8 *));
3810extern void  ck_cast128_key_sched P((CastKeySched *, uint8 *));
3811
3812/*
3813 * ck_cast_ecb_encrypt(output, input, schedule, mode)
3814 * ck_cast_ecb_crypt(data, schedule, mode)
3815 *
3816 * Encrypts the 64-bit "input" according to the CAST key schedule
3817 * "schedule" and places the result in "output".  If "mode" is 0,
3818 * ck_cast_ecb_encrypt will encrypt, otherwise it will decrypt.
3819 * "Output" and "input" can point to the same memory, in which case
3820 * en/decryption will be performed in place.
3821 *
3822 * ck_cast_ecb_crypt accepts input in the form of an array of two
3823 * 32-bit words and performs encryption/decryption in place.
3824 */
3825
3826extern void ck_cast_ecb_encrypt P((uint8 *, uint8 *, CastKeySched *, int));
3827extern void ck_cast_ecb_crypt P((uint32 *, CastKeySched *, int));
3828
3829#endif /* CAST_H */
3830
3831extern encrypt_debug_mode;
3832
3833#define CFB_40  0
3834#define OFB_40  1
3835#ifdef CAST_EXPORT_ENCRYPTION
3836#define FB_CNT  2
3837#else
3838#define CFB_128 2
3839#define OFB_128 3
3840#define FB_CNT  4
3841#endif
3842
3843#define NO_SEND_IV      1
3844#define NO_RECV_IV      2
3845#define NO_KEYID        4
3846#define IN_PROGRESS     (NO_SEND_IV|NO_RECV_IV|NO_KEYID)
3847#define SUCCESS         0
3848#define cFAILED         -1
3849
3850
3851struct cast_fb {
3852        Block temp_feed;
3853        unsigned char fb_feed[64];
3854        int key_isset;
3855        int need_start;
3856        int state[2];
3857        struct cast_stinfo {
3858                Block           str_output;
3859                Block           str_feed;
3860                Block           str_iv;
3861                CastKeySched    str_sched;
3862                int             str_index;
3863        } streams[2];
3864};
3865
3866static struct cast_fb cast_fb[FB_CNT];
3867
3868#define FB64_IV         1
3869#define FB64_IV_OK      2
3870#define FB64_IV_BAD     3
3871
3872
3873static void cast_fb64_stream_iv P((Block, struct cast_stinfo *));
3874static void cast_fb64_init P((struct cast_fb *));
3875static int cast_fb64_start P((struct cast_fb *, int, int));
3876static int cast_fb64_is P((unsigned char *, int, struct cast_fb *));
3877static int cast_fb64_reply P((unsigned char *, int, struct cast_fb *));
3878static int cast_fb64_session P((Session_Key *, int, struct cast_fb *, int));
3879static void cast_fb64_stream_key P((Block, struct cast_stinfo *, int));
3880static int cast_fb64_keyid P((int, unsigned char *, int *, struct cast_fb *));
3881static void _cast_cfb64_encrypt P((unsigned char *,int, struct cast_stinfo *));
3882static int _cast_cfb64_decrypt P((int, struct cast_stinfo *));
3883static void _cast_ofb64_encrypt P((unsigned char *,int, struct cast_stinfo *));
3884static int _cast_ofb64_decrypt P((int, struct cast_stinfo *));
3885
3886#ifndef CAST_EXPORT_ENCRYPTION
3887void
3888cast_cfb64_init(server)
3889        int server;
3890{
3891        cast_fb64_init(&cast_fb[CFB_128]);
3892        cast_fb[CFB_128].fb_feed[4] = ENCTYPE_CAST128_CFB64;
3893}
3894
3895void
3896cast_ofb64_init(server)
3897        int server;
3898{
3899        cast_fb64_init(&cast_fb[OFB_128]);
3900        cast_fb[OFB_128].fb_feed[4] = ENCTYPE_CAST128_OFB64;
3901}
3902#endif
3903
3904void
3905castexp_cfb64_init(server)
3906        int server;
3907{
3908        cast_fb64_init(&cast_fb[CFB_40]);
3909        cast_fb[CFB_40].fb_feed[4] = ENCTYPE_CAST5_40_CFB64;
3910}
3911
3912void
3913castexp_ofb64_init(server)
3914        int server;
3915{
3916        cast_fb64_init(&cast_fb[OFB_40]);
3917        cast_fb[OFB_40].fb_feed[4] = ENCTYPE_CAST5_40_OFB64;
3918}
3919
3920static void
3921cast_fb64_init(fbp)
3922    register struct cast_fb *fbp;
3923{
3924    memset((void *)fbp, 0, sizeof(*fbp));
3925    fbp->key_isset = 0;
3926    fbp->state[0] = fbp->state[1] = cFAILED;
3927    fbp->fb_feed[0] = IAC;
3928    fbp->fb_feed[1] = SB;
3929    fbp->fb_feed[2] = TELOPT_ENCRYPTION;
3930    fbp->fb_feed[3] = ENCRYPT_IS;
3931}
3932
3933/*
3934 * Returns:
3935 *      -1: some error.  Negotiation is done, encryption not ready.
3936 *       0: Successful, initial negotiation all done.
3937 *       1: successful, negotiation not done yet.
3938 *       2: Not yet.  Other things (like getting the key from
3939 *          Kerberos) have to happen before we can continue.
3940 */
3941#ifndef CAST_EXPORT_ENCRYPTION
3942int
3943cast_cfb64_start(dir, server)
3944    int dir;
3945    int server;
3946{
3947    return(cast_fb64_start(&cast_fb[CFB_128], dir, server));
3948}
3949
3950int
3951cast_ofb64_start(dir, server)
3952    int dir;
3953    int server;
3954{
3955    return(cast_fb64_start(&cast_fb[OFB_128], dir, server));
3956}
3957#endif
3958
3959int
3960castexp_cfb64_start(dir, server)
3961    int dir;
3962    int server;
3963{
3964    return(cast_fb64_start(&cast_fb[CFB_40], dir, server));
3965}
3966
3967int
3968castexp_ofb64_start(dir, server)
3969    int dir;
3970    int server;
3971{
3972    return(cast_fb64_start(&cast_fb[OFB_40], dir, server));
3973}
3974
3975static int
3976cast_fb64_start(fbp, dir, server)
3977    struct cast_fb *fbp;
3978    int dir;
3979    int server;
3980{
3981    Block b;
3982    int x;
3983    unsigned char *p;
3984    register int state;
3985
3986    switch (dir) {
3987    case DIR_DECRYPT:
3988        /*
3989         * This is simply a request to have the other side
3990         * start output (our input).  He will negotiate an
3991         * IV so we need not look for it.
3992         */
3993        state = fbp->state[dir-1];
3994        if (state == cFAILED)
3995            state = IN_PROGRESS;
3996        break;
3997
3998    case DIR_ENCRYPT:
3999        state = fbp->state[dir-1];
4000        if (state == cFAILED)
4001            state = IN_PROGRESS;
4002        else if ((state & NO_SEND_IV) == 0)
4003            break;
4004
4005        if (!fbp->key_isset) {
4006            fbp->need_start = 1;
4007            break;
4008        }
4009        state &= ~NO_SEND_IV;
4010        state |= NO_RECV_IV;
4011#ifdef DEBUG
4012        if (encrypt_debug_mode)
4013            printf("Creating new feed\r\n");
4014#endif
4015        /*
4016         * Create a random feed and send it over.
4017         */
4018        ck_cast_ecb_encrypt(fbp->temp_feed, fbp->temp_feed,
4019                          &fbp->streams[dir-1].str_sched, 0);
4020
4021        p = fbp->fb_feed + 3;
4022        *p++ = ENCRYPT_IS;
4023        p++;
4024        *p++ = FB64_IV;
4025        for (x = 0; x < sizeof(Block); ++x) {
4026            if ((*p++ = fbp->temp_feed[x]) == IAC)
4027                *p++ = IAC;
4028        }
4029        *p++ = IAC;
4030        *p++ = SE;
4031
4032        ttol(fbp->fb_feed, p - fbp->fb_feed);
4033        break;
4034    default:
4035        return(cFAILED);
4036    }
4037    return(fbp->state[dir-1] = state);
4038}
4039
4040/*
4041 * Returns:
4042 *      -1: some error.  Negotiation is done, encryption not ready.
4043 *       0: Successful, initial negotiation all done.
4044 *       1: successful, negotiation not done yet.
4045 */
4046#ifndef CAST_EXPORT_ENCRYPTION
4047int
4048cast_cfb64_is(data, cnt)
4049    unsigned char *data;
4050    int cnt;
4051{
4052    return(cast_fb64_is(data, cnt, &cast_fb[CFB_128]));
4053}
4054
4055int
4056cast_ofb64_is(data, cnt)
4057    unsigned char *data;
4058    int cnt;
4059{
4060    return(cast_fb64_is(data, cnt, &cast_fb[OFB_128]));
4061}
4062#endif
4063
4064int
4065castexp_cfb64_is(data, cnt)
4066    unsigned char *data;
4067    int cnt;
4068{
4069    return(cast_fb64_is(data, cnt, &cast_fb[CFB_40]));
4070}
4071
4072int
4073castexp_ofb64_is(data, cnt)
4074    unsigned char *data;
4075    int cnt;
4076{
4077    return(cast_fb64_is(data, cnt, &cast_fb[OFB_40]));
4078}
4079
4080static int
4081cast_fb64_is(data, cnt, fbp)
4082    unsigned char *data;
4083    int cnt;
4084    struct cast_fb *fbp;
4085{
4086    int x;
4087    unsigned char *p;
4088    Block b;
4089    register int state = fbp->state[DIR_DECRYPT-1];
4090
4091    if (cnt-- < 1)
4092        goto failure;
4093
4094#ifdef CK_SSL
4095    if (!TELOPT_SB(TELOPT_START_TLS).start_tls.me_follows)
4096#endif /* CK_SSL */
4097    switch (*data++) {
4098    case FB64_IV:
4099        if (cnt != sizeof(Block)) {
4100#ifdef DEBUG
4101            if (encrypt_debug_mode)
4102                printf("FB64: initial vector failed on size\r\n");
4103#endif
4104            state = cFAILED;
4105            goto failure;
4106        }
4107#ifdef DEBUG
4108        if (encrypt_debug_mode)
4109            printf("FB64: initial vector received\r\n");
4110
4111        if (encrypt_debug_mode)
4112            printf("Initializing Decrypt stream\r\n");
4113#endif
4114        cast_fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]);
4115
4116        p = fbp->fb_feed + 3;
4117        *p++ = ENCRYPT_REPLY;
4118        p++;
4119        *p++ = FB64_IV_OK;
4120        *p++ = IAC;
4121        *p++ = SE;
4122
4123        ttol(fbp->fb_feed, p - fbp->fb_feed);
4124        state = IN_PROGRESS;
4125        break;
4126
4127    default:
4128        /* unknown option type */
4129        /* FALL THROUGH */
4130      failure:
4131        /*
4132        * We failed.  Send an FB64_IV_BAD option
4133        * to the other side so it will know that
4134        * things failed.
4135        */
4136        p = fbp->fb_feed + 3;
4137        *p++ = ENCRYPT_REPLY;
4138        p++;
4139        *p++ = FB64_IV_BAD;
4140        *p++ = IAC;
4141        *p++ = SE;
4142
4143        ttol(fbp->fb_feed, p - fbp->fb_feed);
4144        break;
4145    }
4146    return(fbp->state[DIR_DECRYPT-1] = state);
4147}
4148
4149/*
4150 * Returns:
4151 *      -1: some error.  Negotiation is done, encryption not ready.
4152 *       0: Successful, initial negotiation all done.
4153 *       1: successful, negotiation not done yet.
4154 */
4155#ifndef CAST_EXPORT_ENCRYPTION
4156int
4157cast_cfb64_reply(data, cnt)
4158    unsigned char *data;
4159    int cnt;
4160{
4161    return(cast_fb64_reply(data, cnt, &cast_fb[CFB_128]));
4162}
4163
4164int
4165cast_ofb64_reply(data, cnt)
4166    unsigned char *data;
4167    int cnt;
4168{
4169    return(cast_fb64_reply(data, cnt, &cast_fb[OFB_128]));
4170}
4171#endif
4172
4173int
4174castexp_cfb64_reply(data, cnt)
4175    unsigned char *data;
4176    int cnt;
4177{
4178    return(cast_fb64_reply(data, cnt, &cast_fb[CFB_40]));
4179}
4180
4181int
4182castexp_ofb64_reply(data, cnt)
4183    unsigned char *data;
4184    int cnt;
4185{
4186    return(cast_fb64_reply(data, cnt, &cast_fb[OFB_40]));
4187}
4188
4189static int
4190cast_fb64_reply(data, cnt, fbp)
4191    unsigned char *data;
4192    int cnt;
4193    struct cast_fb *fbp;
4194{
4195    int x;
4196    unsigned char *p;
4197    Block b;
4198    register int state = fbp->state[DIR_ENCRYPT-1];
4199
4200    if (cnt-- < 1)
4201        goto failure;
4202
4203    switch (*data++) {
4204    case FB64_IV_OK:
4205        cast_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
4206        if (state == cFAILED)
4207            state = IN_PROGRESS;
4208        state &= ~NO_RECV_IV;
4209        encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1);
4210        break;
4211
4212    case FB64_IV_BAD:
4213        memset(fbp->temp_feed, 0, sizeof(Block));
4214        cast_fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]);
4215        state = cFAILED;
4216        break;
4217
4218    default:
4219#if 0
4220        if (encrypt_debug_mode) {
4221            printf("Unknown option type: %d\r\n", data[-1]);
4222            printd(data, cnt);
4223            printf("\r\n");
4224        }
4225#endif
4226        /* FALL THROUGH */
4227      failure:
4228        state = cFAILED;
4229        break;
4230    }
4231    return(fbp->state[DIR_ENCRYPT-1] = state);
4232}
4233
4234#ifndef CAST_EXPORT_ENCRYPTION
4235int
4236cast_cfb64_session(key, server)
4237    Session_Key *key;
4238    int server;
4239{
4240    return(cast_fb64_session(key, server, &cast_fb[CFB_128], 1));
4241}
4242
4243int
4244cast_ofb64_session(key, server)
4245    Session_Key *key;
4246    int server;
4247{
4248    return(cast_fb64_session(key, server, &cast_fb[OFB_128], 1));
4249}
4250#endif
4251
4252int
4253castexp_cfb64_session(key, server)
4254    Session_Key *key;
4255    int server;
4256{
4257    return(cast_fb64_session(key, server, &cast_fb[CFB_40], 0));
4258}
4259
4260int
4261castexp_ofb64_session(key, server)
4262    Session_Key *key;
4263    int server;
4264{
4265    return(cast_fb64_session(key, server, &cast_fb[OFB_40], 0));
4266}
4267
4268#define CAST128_KEYLEN  16      /* 128 bits */
4269#define CAST5_40_KEYLEN  5      /*  40 bits */
4270
4271static int
4272cast_fb64_session(key, server, fbp, fs)
4273    Session_Key *key;
4274    int server;
4275    struct cast_fb *fbp;
4276    int fs;
4277{
4278    int klen;
4279    unsigned char * kptr;
4280
4281    if(fs)
4282        klen = CAST128_KEYLEN;
4283    else
4284        klen = CAST5_40_KEYLEN;
4285
4286    if (!key || key->length < klen) {
4287        CHAR buf[80];
4288        sprintf(buf,"Can't set CAST session key (%d < %d)",
4289                key ? key->length : 0, klen);                   /* safe */
4290#ifdef DEBUG
4291        if (encrypt_debug_mode)
4292            printf("%s\r\n",buf);
4293#endif
4294        debug(F110,"cast_fb64_session",buf,0);
4295        return(cFAILED);
4296    }
4297    if(key->length < 2 * klen)
4298        kptr = key->data;
4299    else
4300        kptr = key->data + klen;
4301
4302    if(server) {
4303        cast_fb64_stream_key(kptr, &fbp->streams[DIR_ENCRYPT-1], fs);
4304        cast_fb64_stream_key(key->data, &fbp->streams[DIR_DECRYPT-1], fs);
4305    }
4306    else {
4307        cast_fb64_stream_key(kptr, &fbp->streams[DIR_DECRYPT-1], fs);
4308        cast_fb64_stream_key(key->data, &fbp->streams[DIR_ENCRYPT-1], fs);
4309    }
4310
4311    /* Stuff leftovers into the feed */
4312    if(key->length >= 2 * klen + sizeof(Block))
4313        memcpy(fbp->temp_feed, key->data + 2 * klen, sizeof(Block));
4314    else {
4315#ifdef COMMENT
4316        /* This is a better way of erasing the password */
4317        /* but we do not want to link in libsrp         */
4318        t_random(fbp->temp_feed, sizeof(Block));
4319#else
4320        memset(fbp->temp_feed, 0, sizeof(Block));
4321#endif
4322    }
4323
4324    fbp->key_isset = 1;
4325    /*
4326    * Now look to see if cast_fb64_start() was was waiting for
4327    * the key to show up.  If so, go ahead an call it now
4328    * that we have the key.
4329    */
4330    if (fbp->need_start) {
4331        fbp->need_start = 0;
4332        cast_fb64_start(fbp, DIR_ENCRYPT, server);
4333    }
4334    return(0);
4335}
4336
4337/*
4338 * We only accept a keyid of 0.  If we get a keyid of
4339 * 0, then mark the state as SUCCESS.
4340 */
4341#ifndef CAST_EXPORT_ENCRYPTION
4342int
4343cast_cfb64_keyid(dir, kp, lenp)
4344    int dir, *lenp;
4345    unsigned char *kp;
4346{
4347    return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[CFB_128]));
4348}
4349
4350int
4351cast_ofb64_keyid(dir, kp, lenp)
4352    int dir, *lenp;
4353    unsigned char *kp;
4354{
4355    return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[OFB_128]));
4356}
4357#endif
4358
4359int
4360castexp_cfb64_keyid(dir, kp, lenp)
4361    int dir, *lenp;
4362    unsigned char *kp;
4363{
4364    return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[CFB_40]));
4365}
4366
4367int
4368castexp_ofb64_keyid(dir, kp, lenp)
4369    int dir, *lenp;
4370    unsigned char *kp;
4371{
4372    return(cast_fb64_keyid(dir, kp, lenp, &cast_fb[OFB_40]));
4373}
4374
4375static int
4376cast_fb64_keyid(dir, kp, lenp, fbp)
4377    int dir, *lenp;
4378    unsigned char *kp;
4379    struct cast_fb *fbp;
4380{
4381    register int state = fbp->state[dir-1];
4382
4383    if (*lenp != 1 || (*kp != '\0')) {
4384        *lenp = 0;
4385        return(state);
4386    }
4387
4388    if (state == cFAILED)
4389        state = IN_PROGRESS;
4390
4391    state &= ~NO_KEYID;
4392
4393    return(fbp->state[dir-1] = state);
4394}
4395
4396static void
4397cast_fb64_printsub(data, cnt, buf, buflen, type)
4398    unsigned char *data, *buf, *type;
4399    int cnt, buflen;
4400{
4401    char lbuf[64];
4402    register int i;
4403    char *cp;
4404
4405    buf[buflen-1] = '\0';               /* make sure it's NULL terminated */
4406    buflen -= 1;
4407
4408    switch(data[2]) {
4409    case FB64_IV:
4410        sprintf(lbuf, "%s_IV", type);
4411        cp = lbuf;
4412        goto common;
4413
4414    case FB64_IV_OK:
4415        sprintf(lbuf, "%s_IV_OK", type);
4416        cp = lbuf;
4417        goto common;
4418
4419    case FB64_IV_BAD:
4420        sprintf(lbuf, "%s_IV_BAD", type);
4421        cp = lbuf;
4422        goto common;
4423
4424    default:
4425        sprintf(lbuf, " %d (unknown)", data[2]);
4426        cp = lbuf;
4427      common:
4428        for (; (buflen > 0) && (*buf = *cp++); buf++)
4429            buflen--;
4430        for (i = 3; i < cnt; i++) {
4431            sprintf(lbuf, " %d", data[i]);
4432            for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++)
4433                buflen--;
4434        }
4435        break;
4436    }
4437}
4438
4439void
4440cast_cfb64_printsub(data, cnt, buf, buflen)
4441    unsigned char *data, *buf;
4442    int cnt, buflen;
4443{
4444    cast_fb64_printsub(data, cnt, buf, buflen, "CFB64");
4445}
4446
4447void
4448cast_ofb64_printsub(data, cnt, buf, buflen)
4449    unsigned char *data, *buf;
4450    int cnt, buflen;
4451{
4452    cast_fb64_printsub(data, cnt, buf, buflen, "OFB64");
4453}
4454
4455static void
4456cast_fb64_stream_iv(seed, stp)
4457    Block seed;
4458    register struct cast_stinfo *stp;
4459{
4460    memcpy((void *)stp->str_iv, (void *)seed, sizeof(Block));
4461    memcpy((void *)stp->str_output, (void *)seed, sizeof(Block));
4462
4463    stp->str_index = sizeof(Block);
4464}
4465
4466static void
4467cast_fb64_stream_key(key, stp, fs)
4468    unsigned char * key;
4469    register struct cast_stinfo *stp;
4470    int fs;
4471{
4472#ifndef CAST_EXPORT_ENCRYPTION
4473    if(fs)
4474        ck_cast128_key_sched(&stp->str_sched, key);
4475    else
4476#endif
4477        ck_cast5_40_key_sched(&stp->str_sched, key);
4478
4479    memcpy((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block));
4480
4481    stp->str_index = sizeof(Block);
4482}
4483
4484/*
4485 * CAST 64 bit Cipher Feedback
4486 *
4487 *     key --->+------+
4488 *          +->| CAST |--+
4489 *          |  +------+  |
4490 *          |            v
4491 *  INPUT --(---------->(+)+---> DATA
4492 *          |              |
4493 *          +--------------+
4494 *
4495 *
4496 * Given:
4497 *      iV: Initial vector, 64 bits (8 bytes) long.
4498 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
4499 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
4500 *
4501 *      V0 = CAST(iV, key)
4502 *      On = Dn ^ Vn
4503 *      V(n+1) = CAST(On, key)
4504 */
4505#ifndef CAST_EXPORT_ENCRYPTION
4506void
4507cast_cfb64_encrypt(s, c)
4508        register unsigned char *s;
4509        int c;
4510{
4511    _cast_cfb64_encrypt(s, c, &cast_fb[CFB_128].streams[DIR_ENCRYPT-1]);
4512}
4513#endif
4514
4515void
4516castexp_cfb64_encrypt(s, c)
4517    register unsigned char *s;
4518    int c;
4519{
4520    _cast_cfb64_encrypt(s, c, &cast_fb[CFB_40].streams[DIR_ENCRYPT-1]);
4521}
4522
4523static void
4524_cast_cfb64_encrypt(s, c, stp)
4525    register unsigned char *s;
4526    int c;
4527    register struct cast_stinfo *stp;
4528{
4529    register int index;
4530
4531    index = stp->str_index;
4532    while (c-- > 0) {
4533        if (index == sizeof(Block)) {
4534            Block b;
4535            ck_cast_ecb_encrypt(b, stp->str_output, &stp->str_sched, 0);
4536            memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
4537            index = 0;
4538        }
4539
4540        /* On encryption, we store (feed ^ data) which is cypher */
4541        *s = stp->str_output[index] = (stp->str_feed[index] ^ *s);
4542        s++;
4543        index++;
4544    }
4545    stp->str_index = index;
4546}
4547
4548#ifndef CAST_EXPORT_ENCRYPTION
4549int
4550cast_cfb64_decrypt(data)
4551    int data;
4552{
4553    return _cast_cfb64_decrypt(data, &cast_fb[CFB_128].streams[DIR_DECRYPT-1]);
4554}
4555#endif
4556
4557int
4558castexp_cfb64_decrypt(data)
4559    int data;
4560{
4561    return _cast_cfb64_decrypt(data, &cast_fb[CFB_40].streams[DIR_DECRYPT-1]);
4562}
4563
4564static int
4565_cast_cfb64_decrypt(data, stp)
4566    int data;
4567    register struct cast_stinfo *stp;
4568{
4569    int index;
4570
4571    if (data == -1) {
4572        /*
4573        * Back up one byte.  It is assumed that we will
4574        * never back up more than one byte.  If we do, this
4575        * may or may not work.
4576        */
4577        if (stp->str_index)
4578            --stp->str_index;
4579        return(0);
4580    }
4581
4582    index = stp->str_index++;
4583    if (index == sizeof(Block)) {
4584        Block b;
4585        ck_cast_ecb_encrypt(b, stp->str_output, &stp->str_sched, 0);
4586        memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
4587        stp->str_index = 1;     /* Next time will be 1 */
4588        index = 0;              /* But now use 0 */
4589    }
4590
4591    /* On decryption we store (data) which is cypher. */
4592    stp->str_output[index] = data;
4593    return(data ^ stp->str_feed[index]);
4594}
4595
4596/*
4597 * CAST 64 bit Output Feedback
4598 *
4599 * key --->+------+
4600 *      +->| CAST |--+
4601 *      |  +------+  |
4602 *      +------------+
4603 *                   v
4604 *  INPUT --------->(+) ----> DATA
4605 *
4606 * Given:
4607 *      iV: Initial vector, 64 bits (8 bytes) long.
4608 *      Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt).
4609 *      On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output.
4610 *
4611 *      V0 = CAST(iV, key)
4612 *      V(n+1) = CAST(Vn, key)
4613 *      On = Dn ^ Vn
4614 */
4615#ifndef CAST_EXPORT_ENCRYPTION
4616void
4617cast_ofb64_encrypt(s, c)
4618    register unsigned char *s;
4619    int c;
4620{
4621    _cast_ofb64_encrypt(s, c, &cast_fb[OFB_128].streams[DIR_ENCRYPT-1]);
4622}
4623#endif
4624
4625void
4626castexp_ofb64_encrypt(s, c)
4627    register unsigned char *s;
4628    int c;
4629{
4630  _cast_ofb64_encrypt(s, c, &cast_fb[OFB_40].streams[DIR_ENCRYPT-1]);
4631}
4632
4633static void
4634_cast_ofb64_encrypt(s, c, stp)
4635    register unsigned char *s;
4636    int c;
4637    register struct cast_stinfo *stp;
4638{
4639    register int index;
4640
4641    index = stp->str_index;
4642    while (c-- > 0) {
4643        if (index == sizeof(Block)) {
4644            Block b;
4645            ck_cast_ecb_encrypt(b, stp->str_feed, &stp->str_sched, 0);
4646            memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
4647            index = 0;
4648        }
4649        *s++ ^= stp->str_feed[index];
4650        index++;
4651    }
4652    stp->str_index = index;
4653}
4654
4655#ifndef CAST_EXPORT_ENCRYPTION
4656int
4657cast_ofb64_decrypt(data)
4658    int data;
4659{
4660    return _cast_ofb64_decrypt(data, &cast_fb[OFB_128].streams[DIR_DECRYPT-1]);
4661}
4662#endif
4663
4664int
4665castexp_ofb64_decrypt(data)
4666    int data;
4667{
4668    return _cast_ofb64_decrypt(data, &cast_fb[OFB_40].streams[DIR_DECRYPT-1]);
4669}
4670
4671static int
4672_cast_ofb64_decrypt(data, stp)
4673    int data;
4674    register struct cast_stinfo *stp;
4675{
4676    int index;
4677
4678    if (data == -1) {
4679        /*
4680        * Back up one byte.  It is assumed that we will
4681        * never back up more than one byte.  If we do, this
4682        * may or may not work.
4683        */
4684        if (stp->str_index)
4685            --stp->str_index;
4686        return(0);
4687    }
4688
4689    index = stp->str_index++;
4690    if (index == sizeof(Block)) {
4691        Block b;
4692        ck_cast_ecb_encrypt(b, stp->str_feed, &stp->str_sched, 0);
4693        memcpy((void *)stp->str_feed, (void *)b, sizeof(Block));
4694        stp->str_index = 1;     /* Next time will be 1 */
4695        index = 0;              /* But now use 0 */
4696    }
4697
4698    return(data ^ stp->str_feed[index]);
4699}
4700
4701/*
4702 * Copyright (c) 1997 Stanford University
4703 *
4704 * Permission to use, copy, modify, distribute, and sell this software and
4705 * its documentation for any purpose is hereby granted without fee, provided
4706 * that the above copyright notices and this permission notice appear in
4707 * all copies of the software and related documentation.
4708 *
4709 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
4710 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
4711 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
4712 *
4713 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
4714 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
4715 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
4716 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
4717 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4718 */
4719
4720/*
4721 * cast.c
4722 * Author: Tom Wu
4723 *
4724 * An implementation of the CAST-128 encryption algorithm, as
4725 * specified in RFC 2144.
4726 */
4727
4728/* The first four S-boxes are for encryption/decryption */
4729
4730static uint32 S1[] = {
4731  0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
4732  0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
4733  0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059,
4734  0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
4735  0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
4736  0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
4737  0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159,
4738  0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
4739  0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,
4740  0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
4741  0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38,
4742  0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
4743  0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493,
4744  0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
4745  0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
4746  0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
4747  0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14,
4748  0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
4749  0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8,
4750  0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
4751  0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495,
4752  0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
4753  0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426,
4754  0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
4755  0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
4756  0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
4757  0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,0x7b5a41f0, 0xd37cfbad,
4758  0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
4759  0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464,
4760  0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
4761  0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,0x3f04442f, 0x6188b153,
4762  0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
4763  0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274,
4764  0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
4765  0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,0x580304f0, 0xca042cf1,
4766  0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
4767  0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1,
4768  0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
4769  0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,0x474d6ad7, 0x7c0c5e5c,
4770  0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
4771  0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff,
4772  0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
4773  0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
4774};
4775
4776static uint32 S2[] = {
4777  0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,
4778  0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
4779  0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605,
4780  0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
4781  0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
4782  0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
4783  0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083,
4784  0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
4785  0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f,
4786  0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
4787  0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e,
4788  0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
4789  0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366,
4790  0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
4791  0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
4792  0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
4793  0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6,
4794  0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
4795  0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364,
4796  0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
4797  0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b,
4798  0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
4799  0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c,
4800  0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
4801  0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
4802  0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
4803  0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b,
4804  0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
4805  0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa,
4806  0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
4807  0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028,
4808  0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
4809  0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,
4810  0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
4811  0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
4812  0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
4813  0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb,
4814  0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
4815  0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d,
4816  0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
4817  0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e,
4818  0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
4819  0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
4820};
4821
4822static uint32 S3[] = {
4823  0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,
4824  0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
4825  0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,
4826  0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
4827  0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
4828  0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
4829  0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,
4830  0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
4831  0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e,
4832  0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
4833  0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e,
4834  0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
4835  0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790,
4836  0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
4837  0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
4838  0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
4839  0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8,
4840  0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
4841  0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240,
4842  0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
4843  0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c,
4844  0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
4845  0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788,
4846  0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
4847  0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
4848  0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
4849  0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f,
4850  0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
4851  0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae,
4852  0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
4853  0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9,
4854  0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
4855  0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888,
4856  0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
4857  0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
4858  0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
4859  0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2,
4860  0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
4861  0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d,
4862  0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
4863  0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00,
4864  0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
4865  0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
4866};
4867
4868static uint32 S4[] = {
4869  0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57,
4870  0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
4871  0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd,
4872  0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
4873  0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
4874  0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
4875  0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801,
4876  0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
4877  0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1,
4878  0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
4879  0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3,
4880  0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
4881  0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,
4882  0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
4883  0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
4884  0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
4885  0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,
4886  0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
4887  0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002,
4888  0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
4889  0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7,
4890  0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
4891  0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff,
4892  0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
4893  0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
4894  0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
4895  0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec,
4896  0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
4897  0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e,
4898  0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
4899  0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,
4900  0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
4901  0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f,
4902  0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
4903  0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
4904  0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
4905  0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,
4906  0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
4907  0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,
4908  0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
4909  0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,
4910  0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
4911  0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
4912};
4913
4914/* Encrypt/decrypt one 64-bit block of data */
4915
4916void
4917ck_cast_ecb_encrypt(out, in, sched, mode)
4918    uint8p out;
4919    uint8p in;
4920    CastKeySched * sched;
4921    int mode;           /* zero means encrypt */
4922{
4923    uint32 t[2];
4924
4925#ifdef LITTLE_ENDIAN
4926    t[0] = (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3];
4927    t[1] = (in[4] << 24) | (in[5] << 16) | (in[6] << 8) | in[7];
4928#else
4929    t[0] = *(uint32p) in;
4930    t[1] = *(uint32p) (in + 4);
4931#endif
4932
4933    ck_cast_ecb_crypt(t, sched, mode);
4934
4935#ifdef LITTLE_ENDIAN
4936    out[0] = (t[0] >> 24) & 0xff;
4937    out[1] = (t[0] >> 16) & 0xff;
4938    out[2] = (t[0] >> 8) & 0xff;
4939    out[3] = t[0] & 0xff;
4940    out[4] = (t[1] >> 24) & 0xff;
4941    out[5] = (t[1] >> 16) & 0xff;
4942    out[6] = (t[1] >> 8) & 0xff;
4943    out[7] = t[1] & 0xff;
4944#else
4945    *(uint32p) out = t[0];
4946    *(uint32p) (out + 4) = t[1];
4947#endif
4948}
4949
4950void
4951ck_cast_ecb_crypt(data, sched, mode)
4952    uint32p data;
4953    CastKeySched * sched;
4954    int mode;
4955{
4956    register uint32 L, R, temp;
4957    register struct CastSubkeyPair * kp;
4958    register uint8p Ia, Ib, Ic, Id;
4959    uint32 I;
4960
4961#ifdef LITTLE_ENDIAN
4962    Id = (uint8p) &I;
4963    Ic = Id + 1;
4964    Ib = Ic + 1;
4965    Ia = Ib + 1;
4966#else
4967    Ia = (uint8p) &I;
4968    Ib = Ia + 1;
4969    Ic = Ib + 1;
4970    Id = Ic + 1;
4971#endif
4972
4973    L = data[0];
4974    R = data[1];
4975
4976#define type0(left,right)       \
4977      temp = kp->Km + right;\
4978      I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
4979      left ^= ((S1[*Ia] ^ S2[*Ib]) - S3[*Ic]) + S4[*Id];
4980
4981#define type1(left,right)       \
4982      temp = kp->Km ^ right;\
4983      I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
4984      left ^= ((S1[*Ia] - S2[*Ib]) + S3[*Ic]) ^ S4[*Id];
4985
4986#define type2(left,right)       \
4987      temp = kp->Km - right;\
4988      I = (temp << kp->Kr) | (temp >> (32 - kp->Kr));\
4989      left ^= ((S1[*Ia] + S2[*Ib]) ^ S3[*Ic]) - S4[*Id];
4990
4991    if(mode) {
4992#ifndef CAST_EXPORT_ENCRYPTION
4993        if(sched->ksize > 10) {
4994            kp = &sched->K[15];
4995            type0(L, R); --kp;
4996            type2(R, L); --kp;
4997            type1(L, R); --kp;
4998            type0(R, L); --kp;
4999        }
5000        else
5001#endif
5002        kp = &sched->K[11];
5003        type2(L, R); --kp;
5004        type1(R, L); --kp;
5005        type0(L, R); --kp;
5006        type2(R, L); --kp;
5007        type1(L, R); --kp;
5008        type0(R, L); --kp;
5009        type2(L, R); --kp;
5010        type1(R, L); --kp;
5011        type0(L, R); --kp;
5012        type2(R, L); --kp;
5013        type1(L, R); --kp;
5014        type0(R, L);
5015    }
5016    else {
5017        kp = &sched->K[0];
5018        type0(L, R); ++kp;
5019        type1(R, L); ++kp;
5020        type2(L, R); ++kp;
5021        type0(R, L); ++kp;
5022        type1(L, R); ++kp;
5023        type2(R, L); ++kp;
5024        type0(L, R); ++kp;
5025        type1(R, L); ++kp;
5026        type2(L, R); ++kp;
5027        type0(R, L); ++kp;
5028        type1(L, R); ++kp;
5029        type2(R, L); ++kp;
5030#ifndef CAST_EXPORT_ENCRYPTION
5031        if(sched->ksize > 10) {
5032            type0(L, R); ++kp;
5033            type1(R, L); ++kp;
5034            type2(L, R); ++kp;
5035            type0(R, L);
5036        }
5037#endif
5038    }
5039
5040    data[0] = R;
5041    data[1] = L;
5042}
5043
5044/* The last four S-boxes are for key schedule setup */
5045
5046static uint32 S5[] = {
5047  0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5,
5048  0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
5049  0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd,
5050  0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
5051  0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
5052  0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
5053  0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040,
5054  0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
5055  0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2,
5056  0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
5057  0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399,
5058  0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
5059  0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966,
5060  0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
5061  0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
5062  0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
5063  0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616,
5064  0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
5065  0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419,
5066  0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
5067  0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9,
5068  0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
5069  0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c,
5070  0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
5071  0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
5072  0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
5073  0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d,
5074  0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
5075  0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba,
5076  0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
5077  0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4,
5078  0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
5079  0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c,
5080  0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
5081  0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
5082  0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
5083  0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110,
5084  0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
5085  0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3,
5086  0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
5087  0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d,
5088  0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
5089  0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
5090};
5091
5092static uint32 S6[] = {
5093  0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4,
5094  0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
5095  0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd,
5096  0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
5097  0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
5098  0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
5099  0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0,
5100  0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
5101  0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941,
5102  0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
5103  0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223,
5104  0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
5105  0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6,
5106  0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
5107  0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
5108  0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
5109  0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89,
5110  0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
5111  0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0,
5112  0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
5113  0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4,
5114  0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
5115  0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87,
5116  0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
5117  0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
5118  0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
5119  0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75,
5120  0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
5121  0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283,
5122  0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
5123  0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef,
5124  0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
5125  0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0,
5126  0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
5127  0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
5128  0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
5129  0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf,
5130  0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
5131  0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869,
5132  0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
5133  0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb,
5134  0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
5135  0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
5136};
5137
5138static uint32 S7[] = {
5139  0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912,
5140  0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
5141  0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9,
5142  0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
5143  0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
5144  0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
5145  0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce,
5146  0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
5147  0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7,
5148  0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
5149  0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e,
5150  0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
5151  0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9,
5152  0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
5153  0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
5154  0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
5155  0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c,
5156  0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
5157  0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778,
5158  0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
5159  0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be,
5160  0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
5161  0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310,
5162  0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
5163  0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
5164  0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
5165  0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70,
5166  0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
5167  0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a,
5168  0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
5169  0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c,
5170  0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
5171  0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e,
5172  0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
5173  0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
5174  0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
5175  0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301,
5176  0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
5177  0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4,
5178  0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
5179  0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021,
5180  0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
5181  0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
5182};
5183
5184static uint32 S8[] = {
5185  0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b,
5186  0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
5187  0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c,
5188  0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
5189  0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
5190  0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
5191  0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d,
5192  0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
5193  0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8,
5194  0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
5195  0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04,
5196  0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
5197  0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38,
5198  0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
5199  0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
5200  0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
5201  0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160,
5202  0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
5203  0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2,
5204  0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
5205  0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98,
5206  0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
5207  0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4,
5208  0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
5209  0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
5210  0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
5211  0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5,
5212  0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
5213  0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b,
5214  0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
5215  0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084,
5216  0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
5217  0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a,
5218  0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
5219  0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
5220  0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
5221  0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f,
5222  0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
5223  0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3,
5224  0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
5225  0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1,
5226  0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
5227  0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
5228};
5229
5230/* Initialize a key schedule from a 128-bit key */
5231
5232static void
5233cast_key_sched(sched, key)
5234     CastKeySched * sched;
5235     uint8p key;
5236{
5237    uint8p x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xA, xB, xC, xD, xE, xF;
5238    uint8p z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, zA, zB, zC, zD, zE, zF;
5239    uint32 X03, X47, X8B, XCF, Z03, Z47, Z8B, ZCF;
5240
5241#ifdef LITTLE_ENDIAN
5242    x3 = (uint8p) &X03;  x2 = x3 + 1;  x1 = x2 + 1;  x0 = x1 + 1;
5243    x7 = (uint8p) &X47;  x6 = x7 + 1;  x5 = x6 + 1;  x4 = x5 + 1;
5244    xB = (uint8p) &X8B;  xA = xB + 1;  x9 = xA + 1;  x8 = x9 + 1;
5245    xF = (uint8p) &XCF;  xE = xF + 1;  xD = xE + 1;  xC = xD + 1;
5246    z3 = (uint8p) &Z03;  z2 = z3 + 1;  z1 = z2 + 1;  z0 = z1 + 1;
5247    z7 = (uint8p) &Z47;  z6 = z7 + 1;  z5 = z6 + 1;  z4 = z5 + 1;
5248    zB = (uint8p) &Z8B;  zA = zB + 1;  z9 = zA + 1;  z8 = z9 + 1;
5249    zF = (uint8p) &ZCF;  zE = zF + 1;  zD = zE + 1;  zC = zD + 1;
5250#else
5251    x0 = (uint8p) &X03;  x1 = x0 + 1;  x2 = x1 + 1;  x3 = x2 + 1;
5252    x4 = (uint8p) &X47;  x5 = x4 + 1;  x6 = x5 + 1;  x7 = x6 + 1;
5253    x8 = (uint8p) &X8B;  x9 = x8 + 1;  xA = x9 + 1;  xB = xA + 1;
5254    xC = (uint8p) &XCF;  xD = xC + 1;  xE = xD + 1;  xF = xE + 1;
5255    z0 = (uint8p) &Z03;  z1 = z0 + 1;  z2 = z1 + 1;  z3 = z2 + 1;
5256    z4 = (uint8p) &Z47;  z5 = z4 + 1;  z6 = z5 + 1;  z7 = z6 + 1;
5257    z8 = (uint8p) &Z8B;  z9 = z8 + 1;  zA = z9 + 1;  zB = zA + 1;
5258    zC = (uint8p) &ZCF;  zD = zC + 1;  zE = zD + 1;  zF = zE + 1;
5259#endif
5260
5261#ifdef LITTLE_ENDIAN
5262    *x0 = key[0];
5263    *x1 = key[1];
5264    *x2 = key[2];
5265    *x3 = key[3];
5266    *x4 = key[4];
5267    *x5 = key[5];
5268    *x6 = key[6];
5269    *x7 = key[7];
5270    *x8 = key[8];
5271    *x9 = key[9];
5272    *xA = key[10];
5273    *xB = key[11];
5274    *xC = key[12];
5275    *xD = key[13];
5276    *xE = key[14];
5277    *xF = key[15];
5278#else
5279    X03 = *(uint32p) key;
5280    X47 = *(uint32p) (key + 4);
5281    X8B = *(uint32p) (key + 8);
5282    XCF = *(uint32p) (key + 12);
5283#endif
5284
5285  /* First half of key schedule */
5286
5287    Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
5288    Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
5289    Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
5290    ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
5291
5292    sched->K[0].Km = S5[*z8] ^ S6[*z9] ^ S7[*z7] ^ S8[*z6] ^ S5[*z2];
5293    sched->K[1].Km = S5[*zA] ^ S6[*zB] ^ S7[*z5] ^ S8[*z4] ^ S6[*z6];
5294    sched->K[2].Km = S5[*zC] ^ S6[*zD] ^ S7[*z3] ^ S8[*z2] ^ S7[*z9];
5295    sched->K[3].Km = S5[*zE] ^ S6[*zF] ^ S7[*z1] ^ S8[*z0] ^ S8[*zC];
5296
5297    X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
5298    X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
5299    X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
5300    XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
5301
5302    sched->K[4].Km = S5[*x3] ^ S6[*x2] ^ S7[*xC] ^ S8[*xD] ^ S5[*x8];
5303    sched->K[5].Km = S5[*x1] ^ S6[*x0] ^ S7[*xE] ^ S8[*xF] ^ S6[*xD];
5304    sched->K[6].Km = S5[*x7] ^ S6[*x6] ^ S7[*x8] ^ S8[*x9] ^ S7[*x3];
5305    sched->K[7].Km = S5[*x5] ^ S6[*x4] ^ S7[*xA] ^ S8[*xB] ^ S8[*x7];
5306
5307    Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
5308    Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
5309    Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
5310    ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
5311
5312    sched->K[8].Km = S5[*z3] ^ S6[*z2] ^ S7[*zC] ^ S8[*zD] ^ S5[*z9];
5313    sched->K[9].Km = S5[*z1] ^ S6[*z0] ^ S7[*zE] ^ S8[*zF] ^ S6[*zC];
5314    sched->K[10].Km = S5[*z7] ^ S6[*z6] ^ S7[*z8] ^ S8[*z9] ^ S7[*z2];
5315    sched->K[11].Km = S5[*z5] ^ S6[*z4] ^ S7[*zA] ^ S8[*zB] ^ S8[*z6];
5316
5317    X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
5318    X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
5319    X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
5320    XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
5321
5322    sched->K[12].Km = S5[*x8] ^ S6[*x9] ^ S7[*x7] ^ S8[*x6] ^ S5[*x3];
5323    sched->K[13].Km = S5[*xA] ^ S6[*xB] ^ S7[*x5] ^ S8[*x4] ^ S6[*x7];
5324    sched->K[14].Km = S5[*xC] ^ S6[*xD] ^ S7[*x3] ^ S8[*x2] ^ S7[*x8];
5325    sched->K[15].Km = S5[*xE] ^ S6[*xF] ^ S7[*x1] ^ S8[*x0] ^ S8[*xD];
5326
5327  /* Second half of key schedule - just like first half */
5328
5329    Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
5330    Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
5331    Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
5332    ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
5333
5334    sched->K[0].Kr = (S5[*z8] ^ S6[*z9] ^ S7[*z7] ^ S8[*z6] ^ S5[*z2]) & 0x1f;
5335    sched->K[1].Kr = (S5[*zA] ^ S6[*zB] ^ S7[*z5] ^ S8[*z4] ^ S6[*z6]) & 0x1f;
5336    sched->K[2].Kr = (S5[*zC] ^ S6[*zD] ^ S7[*z3] ^ S8[*z2] ^ S7[*z9]) & 0x1f;
5337    sched->K[3].Kr = (S5[*zE] ^ S6[*zF] ^ S7[*z1] ^ S8[*z0] ^ S8[*zC]) & 0x1f;
5338
5339    X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
5340    X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
5341    X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
5342    XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
5343
5344    sched->K[4].Kr = (S5[*x3] ^ S6[*x2] ^ S7[*xC] ^ S8[*xD] ^ S5[*x8]) & 0x1f;
5345    sched->K[5].Kr = (S5[*x1] ^ S6[*x0] ^ S7[*xE] ^ S8[*xF] ^ S6[*xD]) & 0x1f;
5346    sched->K[6].Kr = (S5[*x7] ^ S6[*x6] ^ S7[*x8] ^ S8[*x9] ^ S7[*x3]) & 0x1f;
5347    sched->K[7].Kr = (S5[*x5] ^ S6[*x4] ^ S7[*xA] ^ S8[*xB] ^ S8[*x7]) & 0x1f;
5348
5349    Z03 = X03 ^ S5[*xD] ^ S6[*xF] ^ S7[*xC] ^ S8[*xE] ^ S7[*x8];
5350    Z47 = X8B ^ S5[*z0] ^ S6[*z2] ^ S7[*z1] ^ S8[*z3] ^ S8[*xA];
5351    Z8B = XCF ^ S5[*z7] ^ S6[*z6] ^ S7[*z5] ^ S8[*z4] ^ S5[*x9];
5352    ZCF = X47 ^ S5[*zA] ^ S6[*z9] ^ S7[*zB] ^ S8[*z8] ^ S6[*xB];
5353
5354    sched->K[8].Kr = (S5[*z3] ^ S6[*z2] ^ S7[*zC] ^ S8[*zD] ^ S5[*z9]) & 0x1f;
5355    sched->K[9].Kr = (S5[*z1] ^ S6[*z0] ^ S7[*zE] ^ S8[*zF] ^ S6[*zC]) & 0x1f;
5356    sched->K[10].Kr = (S5[*z7] ^ S6[*z6] ^ S7[*z8] ^ S8[*z9] ^ S7[*z2]) & 0x1f;
5357    sched->K[11].Kr = (S5[*z5] ^ S6[*z4] ^ S7[*zA] ^ S8[*zB] ^ S8[*z6]) & 0x1f;
5358
5359    X03 = Z8B ^ S5[*z5] ^ S6[*z7] ^ S7[*z4] ^ S8[*z6] ^ S7[*z0];
5360    X47 = Z03 ^ S5[*x0] ^ S6[*x2] ^ S7[*x1] ^ S8[*x3] ^ S8[*z2];
5361    X8B = Z47 ^ S5[*x7] ^ S6[*x6] ^ S7[*x5] ^ S8[*x4] ^ S5[*z1];
5362    XCF = ZCF ^ S5[*xA] ^ S6[*x9] ^ S7[*xB] ^ S8[*x8] ^ S6[*z3];
5363
5364    sched->K[12].Kr = (S5[*x8] ^ S6[*x9] ^ S7[*x7] ^ S8[*x6] ^ S5[*x3]) & 0x1f;
5365    sched->K[13].Kr = (S5[*xA] ^ S6[*xB] ^ S7[*x5] ^ S8[*x4] ^ S6[*x7]) & 0x1f;
5366    sched->K[14].Kr = (S5[*xC] ^ S6[*xD] ^ S7[*x3] ^ S8[*x2] ^ S7[*x8]) & 0x1f;
5367    sched->K[15].Kr = (S5[*xE] ^ S6[*xF] ^ S7[*x1] ^ S8[*x0] ^ S8[*xD]) & 0x1f;
5368}
5369
5370/* Initialize with a full-strength 128-bit key */
5371
5372#ifndef CAST_EXPORT_ENCRYPTION
5373void
5374ck_cast128_key_sched(sched, key)
5375    CastKeySched * sched;
5376    uint8 * key;
5377{
5378    sched->ksize = 16;
5379    cast_key_sched(sched, key);
5380}
5381#endif
5382
5383/* Handle reduced-keysize variants */
5384
5385static void
5386cast5_key_sched(sched, key, sz)
5387    CastKeySched * sched;
5388    uint8 * key;
5389    int sz;
5390{
5391    uint8 buf[16];
5392
5393    sched->ksize = sz;
5394    memset(buf, 0, sizeof(buf));
5395    memcpy(buf, key, sz);
5396    cast_key_sched(sched, buf);
5397}
5398
5399/* 40, 64, and 80-bit keys - all use 12 rounds */
5400
5401void
5402ck_cast5_40_key_sched(sched, key)
5403    CastKeySched * sched;
5404    uint8 * key;
5405{
5406    cast5_key_sched(sched, key, 5);
5407}
5408
5409#ifndef CAST_EXPORT_ENCRYPTION
5410void
5411ck_cast5_64_key_sched(sched, key)
5412     CastKeySched * sched;
5413     uint8 * key;
5414{
5415    cast5_key_sched(sched, key, 8);
5416}
5417
5418void
5419ck_cast5_80_key_sched(sched, key)
5420     CastKeySched * sched;
5421     uint8 * key;
5422{
5423    cast5_key_sched(sched, key, 10);
5424}
5425#endif /* CAST_EXPORT_ENCRYPTION */
5426#endif /* CK_CAST */
5427
5428#ifdef CRYPT_DLL
5429static char *
5430ck_crypt_dll_version()
5431{
5432    return(ckcrpv);
5433}
5434
5435int
5436crypt_dll_init( struct _crypt_dll_init * init )
5437{
5438#ifdef LIBDES
5439    extern int des_check_key;
5440    extern void libdes_dll_init(struct _crypt_dll_init *);
5441    des_check_key = 1;
5442#endif /* LIBDES */
5443
5444    if ( init->version >= 1 ) {
5445        p_ttol = init->p_ttol;
5446        p_dodebug = init->p_dodebug;
5447        p_dohexdump = init->p_dohexdump;
5448        p_tn_debug = init->p_tn_debug;
5449        p_vscrnprintf = init->p_vscrnprintf;
5450        if ( init->version == 1 )
5451            return(1);
5452    }
5453    if ( init->version >= 2 ) {
5454        /* This is a k5_context but we don't want to include krb5.h */
5455        p_k5_context = (void *) init->p_k5_context;
5456        if ( init->version == 2 )
5457            return(1);
5458    }
5459    if ( init->version >= 3 ) {
5460        init->p_install_funcs("encrypt_parse",encrypt_parse);
5461        init->p_install_funcs("encrypt_init",encrypt_init);
5462        init->p_install_funcs("encrypt_session_key",encrypt_session_key);
5463        init->p_install_funcs("encrypt_send_request_start",
5464                              encrypt_send_request_start
5465                              );
5466        init->p_install_funcs("encrypt_request_start",encrypt_request_start);
5467        init->p_install_funcs("encrypt_send_request_end",
5468                              encrypt_send_request_end
5469                              );
5470        init->p_install_funcs("encrypt_request_end",encrypt_request_end);
5471        init->p_install_funcs("encrypt_send_end",encrypt_send_end);
5472        init->p_install_funcs("encrypt_send_support",encrypt_send_support);
5473        init->p_install_funcs("encrypt_is_encrypting",encrypt_is_encrypting);
5474        init->p_install_funcs("encrypt_is_decrypting",encrypt_is_decrypting);
5475        init->p_install_funcs("get_crypt_table",get_crypt_table);
5476        init->p_install_funcs("des_is_weak_key",ck_des_is_weak_key);
5477        libdes_dll_init(init);
5478        if (init->version == 3)
5479          return(1);
5480    }
5481    if ( init->version >= 4 ) {
5482        init->p_install_funcs("crypt_dll_version",ck_crypt_dll_version);
5483        if (init->version == 4)
5484          return(1);
5485    }
5486
5487    if ( init->version >= 5 ) {
5488        p_reqtelmutex = init->p_reqtelmutex;
5489        p_reltelmutex = init->p_reltelmutex;
5490        if (init->version == 5)
5491          return(1);
5492        init->version = 5;
5493        return(1);
5494    }
5495    return(0);
5496}
5497#endif /* CRYPT_DLL */
5498#endif /* CK_ENCRYPTION */
Note: See TracBrowser for help on using the repository browser.