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