/* * Copyright (c) 1985 Corporation for Research and Educational Networking * Copyright (c) 1988 University of Illinois Board of Trustees, Steven * Dorner, and Paul Pomes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Corporation for * Research and Educational Networking (CREN), the University of * Illinois at Urbana, and their contributors. * 4. Neither the name of CREN, the University nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char RcsId[] = "@(#)$Id: cryptit.c,v 1.3 1994/03/11 23:14:20 paul Exp $"; #endif #ifdef PH # ifdef __STDC__ # include # else /* !__STDC__ */ # include # endif /* __STDC__ */ # include # include "qiapi.h" #else /* !PH */ # include "protos.h" #endif /* PH */ #define ROTORSZ 256 #define MASK 0377 #include #include #include #include static char t1[ROTORSZ]; static char t2[ROTORSZ]; static char t3[ROTORSZ]; static int Encrypting = 0; static int ccnt, nchars, n1, n2; static void crypt_init __P((char *)); static void threecpy __P((unsigned char *, unsigned char *)); void crypt_start(pass) char *pass; { n1 = 0; n2 = 0; ccnt = 0; nchars = 0; Encrypting = 1; crypt_init(pass); } char * decrypt(to, from) char *to, *from; { char scratch[4096]; char *sp; int count; count = decode((unsigned char *) scratch, (unsigned char *) from); for (sp = scratch; count--; sp++) { *to++ = t2[(t3[(t1[(*sp + n1) & MASK] + n2) & MASK] - n2) & MASK] - n1; n1++; if (n1 == ROTORSZ) { n1 = 0; n2++; if (n2 == ROTORSZ) n2 = 0; } } *to = '\0'; /* null-terminate */ return (0); } void decrypt_end() { Encrypting = 0; } /* single character decode */ #define DEC(c) (((unsigned char)(c) - '#') & 077) int decode(to, from) unsigned char *to, *from; { int n; int chars; chars = n = DEC(*from++); while (n > 0) { /* * convert groups of 3 bytes (4 Input characters). */ *to++ = DEC(*from) << 2 | DEC(from[1]) >> 4; *to++ = DEC(from[1]) << 4 | DEC(from[2]) >> 2; *to++ = DEC(from[2]) << 6 | DEC(from[3]); from += 4; n -= 3; } return (chars); } static void crypt_init(pw) char *pw; { int ic, i, k, temp; unsigned random; char buf[13]; int seed; char *crypt(); /* must reinitialize the arrays */ for (i = 0; i < ROTORSZ; i++) t1[i] = t2[i] = t3[i] = 0; #ifdef PRE_ENCRYPT strncpy(buf, pw, 13); #else strncpy(buf, crypt(pw, pw), 13); #endif seed = 123; for (i = 0; i < 13; i++) seed = seed * buf[i] + i; for (i = 0; i < ROTORSZ; i++) t1[i] = i; for (i = 0; i < ROTORSZ; i++) { seed = 5 * seed + buf[i % 13]; random = seed % 65521; k = ROTORSZ - 1 - i; ic = (random & MASK) % (k + 1); random >>= 8; temp = t1[k]; t1[k] = t1[ic]; t1[ic] = temp; if (t3[k] != 0) continue; ic = (random & MASK) % k; while (t3[ic] != 0) ic = (ic + 1) % k; t3[k] = ic; t3[ic] = k; } for (i = 0; i < ROTORSZ; i++) t2[t1[i] & MASK] = i; } /* * encrypts a string * first byte of string is encoded length of string * returns length of encoded string */ int encryptit(to, from) char *to, *from; { char scratch[4096]; char *sp; sp = scratch; for (; *from; from++) { *sp++ = t2[(t3[(t1[(*from + n1) & MASK] + n2) & MASK] - n2) & MASK] - n1; n1++; if (n1 == ROTORSZ) { n1 = 0; n2++; if (n2 == ROTORSZ) n2 = 0; } } return (encode(to, scratch, sp - scratch)); } /* * Basic 1 character encoding function to make a char printing. */ #define ENC(c) (((unsigned char)(c) & 077) + '#') int encode(out, buf, n) char *out, *buf; int n; { int i; char *outStart; outStart = out; *out++ = ENC(n); for (i = 0; i < n; buf += 3, i += 3, out += 4) threecpy((unsigned char *) out, (unsigned char *) buf); /* null terminate */ *out = '\0'; return (out - outStart); } static void threecpy(to, from) unsigned char *to, *from; { int c1, c2, c3, c4; c1 = *from >> 2; c2 = (*from << 4) & 060 | (from[1] >> 4) & 017; c3 = (from[1] << 2) & 074 | (from[2] >> 6) & 03; c4 = from[2] & 077; *to++ = ENC(c1); *to++ = ENC(c2); *to++ = ENC(c3); *to = ENC(c4); }