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