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