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
telopt_index(opt)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
telopt_ok(opt)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 *
telopt(opt)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
RequestTelnetMutex(unsigned long x)134 RequestTelnetMutex(unsigned long x)
135 {
136 if ( p_reqtelmutex )
137 return p_reqtelmutex(x);
138 return 0;
139 }
140
141 unsigned long
ReleaseTelnetMutex(void)142 ReleaseTelnetMutex(void)
143 {
144 if ( p_reltelmutex )
145 return p_reltelmutex();
146 return 0;
147 }
148
149 int
ttol(char * s,int n)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
dodebug(int flag,char * s1,char * s2,CK_OFF_T n)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
dohexdump(char * s1,char * s2,int n)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
tn_debug(char * s)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
Vscrnprintf(const char * format,...)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
tn_hex(CHAR * buf,int buflen,CHAR * data,int datalen)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
ck_des_is_weak_key(key)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
unix_time_gmt_unixsec(usecptr)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
des_set_random_generator_seed(Block B)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
des_fixup_key_parity(Block B)404 des_fixup_key_parity(Block B)
405 {
406 des_set_odd_parity(B);
407 return;
408 }
409 #endif /* COMMENT */
410 int
des_new_random_key(Block B)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
get_crypt_table(struct keytab ** pTable,int * pN)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
encrypt_ks_stream(struct kstream_data_block * i,struct kstream_data_block * o)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
decrypt_ks_stream(struct kstream_data_block * i,struct kstream_data_block * o)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
decrypt_ks_hack(unsigned char * buf,int cnt)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
encrypt_parse(unsigned char * parsedat,int end_sub)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
findencryption(int type)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
finddecryption(int type)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
encrypt_init(kstream iks,int type)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
encrypt_send_support(VOID)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
encrypt_support(unsigned char * _typelist,int _cnt)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
encrypt_is(unsigned char * data,int cnt)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
encrypt_reply(unsigned char * data,int cnt)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
encrypt_start(unsigned char * data,int cnt)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
encrypt_dont_support(int type)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
encrypt_session_key(Session_Key * key,int server)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
encrypt_end(VOID)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
encrypt_request_end(VOID)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
encrypt_request_start(VOID)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
encrypt_enc_keyid(unsigned char * keyid,int len)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
encrypt_dec_keyid(unsigned char * keyid,int len)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
encrypt_keyid(struct key_info * kp,unsigned char * keyid,int len)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
encrypt_send_keyid(int dir,unsigned char * keyid,int keylen,int saveit)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
encrypt_auto(int on)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
decrypt_auto(int on)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
encrypt_start_output(int type)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
encrypt_send_end(VOID)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
encrypt_send_request_start(VOID)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
encrypt_send_request_end(VOID)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
encrypt_is_encrypting(VOID)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
encrypt_is_decrypting(VOID)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
encrypt_debug(mode)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
ecb_encrypt(struct des_stinfo * stp,Block in,Block out)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
cfb64_init(server)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
ofb64_init(server)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
fb64_init(fbp)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
cfb64_start(dir,server)2064 cfb64_start(dir, server)
2065 int dir;
2066 int server;
2067 {
2068 return(fb64_start(&des_fb[CFB], dir, server));
2069 }
2070 int
ofb64_start(dir,server)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
fb64_start(fbp,dir,server)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
cfb64_is(data,cnt)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
ofb64_is(data,cnt)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
fb64_is(data,cnt,fbp)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
cfb64_reply(data,cnt)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
ofb64_reply(data,cnt)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
fb64_reply(data,cnt,fbp)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
cfb64_session(key,server)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
ofb64_session(key,server)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
fb64_session(key,server,fbp)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
cfb64_keyid(dir,kp,lenp)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
ofb64_keyid(dir,kp,lenp)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
fb64_keyid(dir,kp,lenp,fbp)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
fb64_stream_iv(seed,stp)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
fb64_stream_key(key,stp)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
cfb64_encrypt(s,c)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
cfb64_decrypt(data)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
ofb64_encrypt(s,c)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
ofb64_decrypt(data)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
des3_cfb64_init(server)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
des3_ofb64_init(server)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
des3_fb64_init(fbp)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
des3_cfb64_start(dir,server)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
des3_ofb64_start(dir,server)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
des3_fb64_start(fbp,dir,server)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
des3_cfb64_is(data,cnt)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
des3_ofb64_is(data,cnt)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
des3_fb64_is(data,cnt,fbp)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
des3_cfb64_reply(data,cnt)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
des3_ofb64_reply(data,cnt)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
des3_fb64_reply(data,cnt,fbp)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
des3_cfb64_session(key,server)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
des3_ofb64_session(key,server)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
des3_fb64_session(key,server,fbp)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
des3_cfb64_keyid(dir,kp,lenp)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
des3_ofb64_keyid(dir,kp,lenp)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
des3_fb64_keyid(dir,kp,lenp,fbp)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
des3_fb64_stream_iv(seed,stp)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
des3_fb64_stream_key(key,stp)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
des3_cfb64_encrypt(s,c)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
des3_cfb64_decrypt(data)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
des3_ofb64_encrypt(s,c)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
des3_ofb64_decrypt(data)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
cast_cfb64_init(server)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
cast_ofb64_init(server)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
castexp_cfb64_init(server)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
castexp_ofb64_init(server)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
cast_fb64_init(fbp)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
cast_cfb64_start(dir,server)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
cast_ofb64_start(dir,server)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
castexp_cfb64_start(dir,server)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
castexp_ofb64_start(dir,server)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
cast_fb64_start(fbp,dir,server)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
cast_cfb64_is(data,cnt)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
cast_ofb64_is(data,cnt)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
castexp_cfb64_is(data,cnt)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
castexp_ofb64_is(data,cnt)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
cast_fb64_is(data,cnt,fbp)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
cast_cfb64_reply(data,cnt)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
cast_ofb64_reply(data,cnt)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
castexp_cfb64_reply(data,cnt)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
castexp_ofb64_reply(data,cnt)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
cast_fb64_reply(data,cnt,fbp)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
cast_cfb64_session(key,server)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
cast_ofb64_session(key,server)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
castexp_cfb64_session(key,server)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
castexp_ofb64_session(key,server)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
cast_fb64_session(key,server,fbp,fs)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
cast_cfb64_keyid(dir,kp,lenp)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
cast_ofb64_keyid(dir,kp,lenp)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
castexp_cfb64_keyid(dir,kp,lenp)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
castexp_ofb64_keyid(dir,kp,lenp)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
cast_fb64_keyid(dir,kp,lenp,fbp)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
cast_fb64_printsub(data,cnt,buf,buflen,type)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
cast_cfb64_printsub(data,cnt,buf,buflen)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
cast_ofb64_printsub(data,cnt,buf,buflen)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
cast_fb64_stream_iv(seed,stp)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
cast_fb64_stream_key(key,stp,fs)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
cast_cfb64_encrypt(s,c)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
castexp_cfb64_encrypt(s,c)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
_cast_cfb64_encrypt(s,c,stp)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
cast_cfb64_decrypt(data)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
castexp_cfb64_decrypt(data)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
_cast_cfb64_decrypt(data,stp)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
cast_ofb64_encrypt(s,c)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
castexp_ofb64_encrypt(s,c)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
_cast_ofb64_encrypt(s,c,stp)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
cast_ofb64_decrypt(data)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
castexp_ofb64_decrypt(data)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
_cast_ofb64_decrypt(data,stp)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
ck_cast_ecb_encrypt(out,in,sched,mode)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
ck_cast_ecb_crypt(data,sched,mode)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
cast_key_sched(sched,key)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
ck_cast128_key_sched(sched,key)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
cast5_key_sched(sched,key,sz)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
ck_cast5_40_key_sched(sched,key)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
ck_cast5_64_key_sched(sched,key)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
ck_cast5_80_key_sched(sched,key)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 *
ck_crypt_dll_version()5475 ck_crypt_dll_version()
5476 {
5477 return(ckcrpv);
5478 }
5479
5480 int
crypt_dll_init(struct _crypt_dll_init * init)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
fatal(char * msg)5556 fatal(char *msg) {
5557 if (!msg) msg = "";
5558
5559 printf(msg);
5560 exit(1); /* Exit indicating failure */
5561 }
5562
5563 void *
kmalloc(size_t size)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 *
krealloc(void * ptr,size_t new_size)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
kfree(void * ptr)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 *
kstrdup(const char * str)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 */
5623