147038Sbostic /* 247038Sbostic * Copyright (c) 1989 The Regents of the University of California. 347038Sbostic * All rights reserved. 447038Sbostic * 547038Sbostic * This code is derived from software contributed to Berkeley by 647038Sbostic * Tom Truscott. 747038Sbostic * 848731Sbostic * %sccs.include.redist.c% 947038Sbostic */ 1047038Sbostic 1126545Sdonn #if defined(LIBC_SCCS) && !defined(lint) 12*49804Sbostic static char sccsid[] = "@(#)crypt.c 5.9 (Berkeley) 05/18/91"; 1347038Sbostic #endif /* LIBC_SCCS and not lint */ 1422083Smckusick 1546597Sdonn #include <unistd.h> 1648485Sbostic #include <pwd.h> 1746597Sdonn 181958Swnj /* 1947038Sbostic * UNIX password, and DES, encryption. 2047038Sbostic * By Tom Truscott, trt@rti.rti.org, 2147038Sbostic * from algorithms by Robert W. Baldwin and James Gillogly. 2247038Sbostic * 2347038Sbostic * References: 2447038Sbostic * "Mathematical Cryptology for Computer Scientists and Mathematicians," 2547038Sbostic * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 2647038Sbostic * 2747038Sbostic * "Password Security: A Case History," R. Morris and Ken Thompson, 2847038Sbostic * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 2947038Sbostic * 3047038Sbostic * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 3147038Sbostic * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 321958Swnj */ 331958Swnj 3447038Sbostic /* ===== Configuration ==================== */ 3547038Sbostic 361958Swnj /* 3747038Sbostic * define "MUST_ALIGN" if your compiler cannot load/store 3847038Sbostic * long integers at arbitrary (e.g. odd) memory locations. 3947038Sbostic * (Either that or never pass unaligned addresses to des_cipher!) 401958Swnj */ 4147038Sbostic #if !defined(vax) 4247038Sbostic #define MUST_ALIGN 4347038Sbostic #endif 441958Swnj 451958Swnj /* 4647038Sbostic * define "LONG_IS_32_BITS" only if sizeof(long)==4. 4747038Sbostic * This avoids use of bit fields (your compiler may be sloppy with them). 481958Swnj */ 4947038Sbostic #if !defined(cray) 5047038Sbostic #define LONG_IS_32_BITS 5147038Sbostic #endif 521958Swnj 531958Swnj /* 5447038Sbostic * define "B64" to be the declaration for a 64 bit integer. 5547038Sbostic * XXX this feature is currently unused, see "endian" comment below. 561958Swnj */ 5747038Sbostic #if defined(cray) 5847038Sbostic #define B64 long 5947038Sbostic #endif 6047038Sbostic #if defined(convex) 6147038Sbostic #define B64 long long 6247038Sbostic #endif 631958Swnj 641958Swnj /* 6547038Sbostic * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 6647038Sbostic * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 6748484Sbostic * little effect on crypt(). 681958Swnj */ 6947038Sbostic #if defined(notdef) 7047038Sbostic #define LARGEDATA 7147038Sbostic #endif 721958Swnj 7348484Sbostic /* compile with "-DSTATIC=int" when profiling */ 7448484Sbostic #ifndef STATIC 7547038Sbostic #define STATIC static 7648484Sbostic #endif 7748484Sbostic STATIC init_des(), init_perm(), permute(); 7847038Sbostic #ifdef DEBUG 7947038Sbostic STATIC prtab(); 8047038Sbostic #endif 811958Swnj 8247038Sbostic /* ==================================== */ 8347038Sbostic 841958Swnj /* 8547038Sbostic * Cipher-block representation (Bob Baldwin): 8647038Sbostic * 8747038Sbostic * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 8847038Sbostic * representation is to store one bit per byte in an array of bytes. Bit N of 8947038Sbostic * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 9047038Sbostic * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 9147038Sbostic * first byte, 9..16 in the second, and so on. The DES spec apparently has 9247038Sbostic * bit 1 in the MSB of the first byte, but that is particularly noxious so we 9347038Sbostic * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 9447038Sbostic * the MSB of the first byte. Specifically, the 64-bit input data and key are 9547038Sbostic * converted to LSB format, and the output 64-bit block is converted back into 9647038Sbostic * MSB format. 9747038Sbostic * 9847038Sbostic * DES operates internally on groups of 32 bits which are expanded to 48 bits 9947038Sbostic * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 10047038Sbostic * the computation, the expansion is applied only once, the expanded 10147038Sbostic * representation is maintained during the encryption, and a compression 10247038Sbostic * permutation is applied only at the end. To speed up the S-box lookups, 10347038Sbostic * the 48 bits are maintained as eight 6 bit groups, one per byte, which 10447038Sbostic * directly feed the eight S-boxes. Within each byte, the 6 bits are the 10547038Sbostic * most significant ones. The low two bits of each byte are zero. (Thus, 10647038Sbostic * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 10747038Sbostic * first byte in the eight byte representation, bit 2 of the 48 bit value is 10848484Sbostic * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 10947038Sbostic * used, in which the output is the 64 bit result of an S-box lookup which 11047038Sbostic * has been permuted by P and expanded by E, and is ready for use in the next 11147038Sbostic * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 11247038Sbostic * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 11347038Sbostic * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 11447038Sbostic * "salt" are also converted to this 8*(6+2) format. The SPE table size is 11547038Sbostic * 8*64*8 = 4K bytes. 11647038Sbostic * 11747038Sbostic * To speed up bit-parallel operations (such as XOR), the 8 byte 11847038Sbostic * representation is "union"ed with 32 bit values "i0" and "i1", and, on 11947038Sbostic * machines which support it, a 64 bit value "b64". This data structure, 12047038Sbostic * "C_block", has two problems. First, alignment restrictions must be 12147038Sbostic * honored. Second, the byte-order (e.g. little-endian or big-endian) of 12247038Sbostic * the architecture becomes visible. 12347038Sbostic * 12447038Sbostic * The byte-order problem is unfortunate, since on the one hand it is good 12547038Sbostic * to have a machine-independent C_block representation (bits 1..8 in the 12647038Sbostic * first byte, etc.), and on the other hand it is good for the LSB of the 12747038Sbostic * first byte to be the LSB of i0. We cannot have both these things, so we 12847038Sbostic * currently use the "little-endian" representation and avoid any multi-byte 12947038Sbostic * operations that depend on byte order. This largely precludes use of the 13047038Sbostic * 64-bit datatype since the relative order of i0 and i1 are unknown. It 13147038Sbostic * also inhibits grouping the SPE table to look up 12 bits at a time. (The 13247038Sbostic * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 13348484Sbostic * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 13447038Sbostic * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 13547038Sbostic * requires a 128 kilobyte table, so perhaps this is not a big loss. 13647038Sbostic * 13747038Sbostic * Permutation representation (Jim Gillogly): 13847038Sbostic * 13947038Sbostic * A transformation is defined by its effect on each of the 8 bytes of the 14047038Sbostic * 64-bit input. For each byte we give a 64-bit output that has the bits in 14147038Sbostic * the input distributed appropriately. The transformation is then the OR 14247038Sbostic * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 14347038Sbostic * each transformation. Unless LARGEDATA is defined, however, a more compact 14447038Sbostic * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 14547038Sbostic * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 14647038Sbostic * is slower but tolerable, particularly for password encryption in which 14747038Sbostic * the SPE transformation is iterated many times. The small tables total 9K 14847038Sbostic * bytes, the large tables total 72K bytes. 14947038Sbostic * 15047038Sbostic * The transformations used are: 15147038Sbostic * IE3264: MSB->LSB conversion, initial permutation, and expansion. 15247038Sbostic * This is done by collecting the 32 even-numbered bits and applying 15347038Sbostic * a 32->64 bit transformation, and then collecting the 32 odd-numbered 15447038Sbostic * bits and applying the same transformation. Since there are only 15547038Sbostic * 32 input bits, the IE3264 transformation table is half the size of 15647038Sbostic * the usual table. 15747038Sbostic * CF6464: Compression, final permutation, and LSB->MSB conversion. 15847038Sbostic * This is done by two trivial 48->32 bit compressions to obtain 15947038Sbostic * a 64-bit block (the bit numbering is given in the "CIFP" table) 16047038Sbostic * followed by a 64->64 bit "cleanup" transformation. (It would 16147038Sbostic * be possible to group the bits in the 64-bit block so that 2 16247038Sbostic * identical 32->32 bit transformations could be used instead, 16347038Sbostic * saving a factor of 4 in space and possibly 2 in time, but 16447038Sbostic * byte-ordering and other complications rear their ugly head. 16547038Sbostic * Similar opportunities/problems arise in the key schedule 16647038Sbostic * transforms.) 16747038Sbostic * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 16847038Sbostic * This admittedly baroque 64->64 bit transformation is used to 16947038Sbostic * produce the first code (in 8*(6+2) format) of the key schedule. 17047038Sbostic * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 17147038Sbostic * It would be possible to define 15 more transformations, each 17247038Sbostic * with a different rotation, to generate the entire key schedule. 17347038Sbostic * To save space, however, we instead permute each code into the 17447038Sbostic * next by using a transformation that "undoes" the PC2 permutation, 17547038Sbostic * rotates the code, and then applies PC2. Unfortunately, PC2 17647038Sbostic * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 17747038Sbostic * invertible. We get around that problem by using a modified PC2 17847038Sbostic * which retains the 8 otherwise-lost bits in the unused low-order 17947038Sbostic * bits of each byte. The low-order bits are cleared when the 18047038Sbostic * codes are stored into the key schedule. 18147038Sbostic * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 18247038Sbostic * This is faster than applying PC2ROT[0] twice, 18347038Sbostic * 18447038Sbostic * The Bell Labs "salt" (Bob Baldwin): 18547038Sbostic * 18647038Sbostic * The salting is a simple permutation applied to the 48-bit result of E. 18747038Sbostic * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 18847038Sbostic * i+24 of the result are swapped. The salt is thus a 24 bit number, with 18947038Sbostic * 16777216 possible values. (The original salt was 12 bits and could not 19047038Sbostic * swap bits 13..24 with 36..48.) 19147038Sbostic * 19248484Sbostic * It is possible, but ugly, to warp the SPE table to account for the salt 19348484Sbostic * permutation. Fortunately, the conditional bit swapping requires only 19448484Sbostic * about four machine instructions and can be done on-the-fly with about an 19548484Sbostic * 8% performance penalty. 1961958Swnj */ 19748484Sbostic 19847038Sbostic typedef union { 19947038Sbostic unsigned char b[8]; 20047038Sbostic struct { 20147038Sbostic #if defined(LONG_IS_32_BITS) 20247038Sbostic /* long is often faster than a 32-bit bit field */ 20347038Sbostic long i0; 20447038Sbostic long i1; 20547038Sbostic #else 20647038Sbostic long i0: 32; 20747038Sbostic long i1: 32; 20847038Sbostic #endif 20947038Sbostic } b32; 21047038Sbostic #if defined(B64) 21147038Sbostic B64 b64; 21247038Sbostic #endif 21347038Sbostic } C_block; 2141958Swnj 2151958Swnj /* 21647038Sbostic * Convert twenty-four-bit long in host-order 21747038Sbostic * to six bits (and 2 low-order zeroes) per char little-endian format. 2181958Swnj */ 21947038Sbostic #define TO_SIX_BIT(rslt, src) { \ 22047038Sbostic C_block cvt; \ 22147038Sbostic cvt.b[0] = src; src >>= 6; \ 22247038Sbostic cvt.b[1] = src; src >>= 6; \ 22347038Sbostic cvt.b[2] = src; src >>= 6; \ 22447038Sbostic cvt.b[3] = src; \ 22547038Sbostic rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 22647038Sbostic } 2271958Swnj 2281958Swnj /* 22947038Sbostic * These macros may someday permit efficient use of 64-bit integers. 23017337Sralph */ 23147038Sbostic #define ZERO(d,d0,d1) d0 = 0, d1 = 0 23247038Sbostic #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 23347038Sbostic #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 23447038Sbostic #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 23547038Sbostic #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 23647038Sbostic #define DCL_BLOCK(d,d0,d1) long d0, d1 23747038Sbostic 23847038Sbostic #if defined(LARGEDATA) 23947038Sbostic /* Waste memory like crazy. Also, do permutations in line */ 24047038Sbostic #define LGCHUNKBITS 3 24147038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 24247038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 24347038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 24447038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 24547038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 24647038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \ 24747038Sbostic OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 24847038Sbostic OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 24947038Sbostic OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 25047038Sbostic OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 25147038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 25247038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 25347038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 25447038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 25547038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 25647038Sbostic #else 25747038Sbostic /* "small data" */ 25847038Sbostic #define LGCHUNKBITS 2 25947038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 26047038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 26147038Sbostic { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 26247038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 26347038Sbostic { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 26447038Sbostic 26547038Sbostic STATIC 26647038Sbostic permute(cp, out, p, chars_in) 26747038Sbostic unsigned char *cp; 26847038Sbostic C_block *out; 26947038Sbostic register C_block *p; 27047038Sbostic int chars_in; 27147038Sbostic { 27247038Sbostic register DCL_BLOCK(D,D0,D1); 27347038Sbostic register C_block *tp; 27447038Sbostic register int t; 27547038Sbostic 27647038Sbostic ZERO(D,D0,D1); 27747038Sbostic do { 27847038Sbostic t = *cp++; 27947038Sbostic tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 28047038Sbostic tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 28147038Sbostic } while (--chars_in > 0); 28247038Sbostic STORE(D,D0,D1,*out); 28347038Sbostic } 28447038Sbostic #endif /* LARGEDATA */ 28547038Sbostic 28647038Sbostic 28747038Sbostic /* ===== (mostly) Standard DES Tables ==================== */ 28847038Sbostic 28947038Sbostic static unsigned char IP[] = { /* initial permutation */ 29047038Sbostic 58, 50, 42, 34, 26, 18, 10, 2, 29147038Sbostic 60, 52, 44, 36, 28, 20, 12, 4, 29247038Sbostic 62, 54, 46, 38, 30, 22, 14, 6, 29347038Sbostic 64, 56, 48, 40, 32, 24, 16, 8, 29447038Sbostic 57, 49, 41, 33, 25, 17, 9, 1, 29547038Sbostic 59, 51, 43, 35, 27, 19, 11, 3, 29647038Sbostic 61, 53, 45, 37, 29, 21, 13, 5, 29747038Sbostic 63, 55, 47, 39, 31, 23, 15, 7, 29817337Sralph }; 29917337Sralph 30047038Sbostic /* The final permutation is the inverse of IP - no table is necessary */ 30147038Sbostic 30247038Sbostic static unsigned char ExpandTr[] = { /* expansion operation */ 30347038Sbostic 32, 1, 2, 3, 4, 5, 30447038Sbostic 4, 5, 6, 7, 8, 9, 30547038Sbostic 8, 9, 10, 11, 12, 13, 30647038Sbostic 12, 13, 14, 15, 16, 17, 30747038Sbostic 16, 17, 18, 19, 20, 21, 30847038Sbostic 20, 21, 22, 23, 24, 25, 30947038Sbostic 24, 25, 26, 27, 28, 29, 31047038Sbostic 28, 29, 30, 31, 32, 1, 31147038Sbostic }; 31247038Sbostic 31347038Sbostic static unsigned char PC1[] = { /* permuted choice table (key) */ 31447038Sbostic 57, 49, 41, 33, 25, 17, 9, 31547038Sbostic 1, 58, 50, 42, 34, 26, 18, 31647038Sbostic 10, 2, 59, 51, 43, 35, 27, 31747038Sbostic 19, 11, 3, 60, 52, 44, 36, 31847038Sbostic 31947038Sbostic 63, 55, 47, 39, 31, 23, 15, 32047038Sbostic 7, 62, 54, 46, 38, 30, 22, 32147038Sbostic 14, 6, 61, 53, 45, 37, 29, 32247038Sbostic 21, 13, 5, 28, 20, 12, 4, 32347038Sbostic }; 32447038Sbostic 32547038Sbostic static unsigned char Rotates[] = { /* number of rotations of PC1 */ 32647038Sbostic 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 32747038Sbostic }; 32847038Sbostic 32947038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 33047038Sbostic static unsigned char PC2[] = { /* permuted choice key (table) */ 33147038Sbostic 9, 18, 14, 17, 11, 24, 1, 5, 33247038Sbostic 22, 25, 3, 28, 15, 6, 21, 10, 33347038Sbostic 35, 38, 23, 19, 12, 4, 26, 8, 33447038Sbostic 43, 54, 16, 7, 27, 20, 13, 2, 33547038Sbostic 33647038Sbostic 0, 0, 41, 52, 31, 37, 47, 55, 33747038Sbostic 0, 0, 30, 40, 51, 45, 33, 48, 33847038Sbostic 0, 0, 44, 49, 39, 56, 34, 53, 33947038Sbostic 0, 0, 46, 42, 50, 36, 29, 32, 34047038Sbostic }; 34147038Sbostic 34247038Sbostic static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 34347038Sbostic /* S[1] */ 34447038Sbostic 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 34547038Sbostic 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 34647038Sbostic 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 34747038Sbostic 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 34847038Sbostic /* S[2] */ 34947038Sbostic 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 35047038Sbostic 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 35147038Sbostic 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 35247038Sbostic 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 35347038Sbostic /* S[3] */ 35447038Sbostic 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 35547038Sbostic 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 35647038Sbostic 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 35747038Sbostic 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 35847038Sbostic /* S[4] */ 35947038Sbostic 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 36047038Sbostic 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 36147038Sbostic 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 36247038Sbostic 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 36347038Sbostic /* S[5] */ 36447038Sbostic 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 36547038Sbostic 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 36647038Sbostic 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 36747038Sbostic 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 36847038Sbostic /* S[6] */ 36947038Sbostic 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 37047038Sbostic 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 37147038Sbostic 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 37247038Sbostic 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 37347038Sbostic /* S[7] */ 37447038Sbostic 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 37547038Sbostic 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 37647038Sbostic 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 37747038Sbostic 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 37847038Sbostic /* S[8] */ 37947038Sbostic 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 38047038Sbostic 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 38147038Sbostic 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 38247038Sbostic 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 38347038Sbostic }; 38447038Sbostic 38547038Sbostic static unsigned char P32Tr[] = { /* 32-bit permutation function */ 38647038Sbostic 16, 7, 20, 21, 38747038Sbostic 29, 12, 28, 17, 38847038Sbostic 1, 15, 23, 26, 38947038Sbostic 5, 18, 31, 10, 39047038Sbostic 2, 8, 24, 14, 39147038Sbostic 32, 27, 3, 9, 39247038Sbostic 19, 13, 30, 6, 39347038Sbostic 22, 11, 4, 25, 39447038Sbostic }; 39547038Sbostic 39647038Sbostic static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 39747038Sbostic 1, 2, 3, 4, 17, 18, 19, 20, 39847038Sbostic 5, 6, 7, 8, 21, 22, 23, 24, 39947038Sbostic 9, 10, 11, 12, 25, 26, 27, 28, 40047038Sbostic 13, 14, 15, 16, 29, 30, 31, 32, 40147038Sbostic 40247038Sbostic 33, 34, 35, 36, 49, 50, 51, 52, 40347038Sbostic 37, 38, 39, 40, 53, 54, 55, 56, 40447038Sbostic 41, 42, 43, 44, 57, 58, 59, 60, 40547038Sbostic 45, 46, 47, 48, 61, 62, 63, 64, 40647038Sbostic }; 40747038Sbostic 40847038Sbostic static unsigned char itoa64[] = /* 0..63 => ascii-64 */ 40947038Sbostic "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 41047038Sbostic 41147038Sbostic 41247038Sbostic /* ===== Tables that are initialized at run time ==================== */ 41347038Sbostic 41447038Sbostic 41547038Sbostic static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ 41647038Sbostic 41747038Sbostic /* Initial key schedule permutation */ 41847038Sbostic static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 41947038Sbostic 42047038Sbostic /* Subsequent key schedule rotation permutations */ 42147038Sbostic static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 42247038Sbostic 42347038Sbostic /* Initial permutation/expansion table */ 42447038Sbostic static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 42547038Sbostic 42647038Sbostic /* Table that combines the S, P, and E operations. */ 42747038Sbostic static long SPE[2][8][64]; 42847038Sbostic 42947038Sbostic /* compressed/interleaved => final permutation table */ 43047038Sbostic static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 43147038Sbostic 43247038Sbostic 43347038Sbostic /* ==================================== */ 43447038Sbostic 43547038Sbostic 43647038Sbostic static C_block constdatablock; /* encryption constant */ 43747038Sbostic static char cryptresult[1+4+4+11+1]; /* encrypted result */ 43847038Sbostic 43917337Sralph /* 44048484Sbostic * Return a pointer to static data consisting of the "setting" 44148484Sbostic * followed by an encryption produced by the "key" and "setting". 4421958Swnj */ 44347038Sbostic char * 44447038Sbostic crypt(key, setting) 44547038Sbostic register const char *key; 44647038Sbostic register const char *setting; 4471958Swnj { 44847038Sbostic register char *encp; 44947038Sbostic register long i; 45048484Sbostic register int t; 45147038Sbostic long salt; 45247038Sbostic int num_iter, salt_size, key_size; 45347038Sbostic C_block keyblock, rsltblock; 4541958Swnj 45548484Sbostic for (i = 0; i < 8; i++) { 45648484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 45747038Sbostic key++; 45848484Sbostic keyblock.b[i] = t; 45948484Sbostic } 460*49804Sbostic if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */ 461*49804Sbostic return(NULL); 46247038Sbostic 46347038Sbostic encp = &cryptresult[0]; 46448485Sbostic switch (*setting) { 46548485Sbostic case _PASSWORD_EFMT1: 46647038Sbostic *encp++ = *setting++; 46747038Sbostic 46847038Sbostic /* get iteration count */ 46947038Sbostic num_iter = 0; 47047038Sbostic for (i = 4; --i >= 0; ) { 47148484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 47248484Sbostic t = '.'; 47348484Sbostic encp[i] = t; 47448484Sbostic num_iter = (num_iter<<6) | a64toi[t]; 47547038Sbostic } 47647038Sbostic setting += 4; 47747038Sbostic encp += 4; 47847038Sbostic salt_size = 4; 47947038Sbostic key_size = 128; 48048485Sbostic break; 48148485Sbostic default: 48248485Sbostic num_iter = 25; 48348485Sbostic salt_size = 2; 48448485Sbostic key_size = 8; 48547038Sbostic } 48647038Sbostic 48747038Sbostic salt = 0; 48847038Sbostic for (i = salt_size; --i >= 0; ) { 48948484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 49048484Sbostic t = '.'; 49148484Sbostic encp[i] = t; 49248484Sbostic salt = (salt<<6) | a64toi[t]; 49347038Sbostic } 49447038Sbostic encp += salt_size; 495*49804Sbostic if (des_cipher((char *)&constdatablock, (char *)&rsltblock, 496*49804Sbostic salt, num_iter)) 497*49804Sbostic return(NULL); 49847038Sbostic 4991958Swnj /* 50047038Sbostic * encrypt the remainder of the password 8 characters at a time. 5011958Swnj */ 50247038Sbostic while ((key_size -= 8) > 0 && *key) { 50347038Sbostic C_block xdatablock; 50447038Sbostic 50548484Sbostic for (i = 0; i < 8; i++) { 50648484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 50747038Sbostic key++; 50848484Sbostic keyblock.b[i] = t; 50948484Sbostic if (t == 0) 51047038Sbostic break; /* pad out with previous key */ 51148484Sbostic } 512*49804Sbostic if (des_setkey((char *)keyblock.b)) 513*49804Sbostic return(NULL); 514*49804Sbostic if (des_cipher((char *)&constdatablock, 515*49804Sbostic (char *)&xdatablock, 0L, 1)) 516*49804Sbostic return(NULL); 51747038Sbostic rsltblock.b32.i0 ^= xdatablock.b32.i0; 51847038Sbostic rsltblock.b32.i1 ^= xdatablock.b32.i1; 5191958Swnj } 52047038Sbostic 5211958Swnj /* 52247038Sbostic * Encode the 64 cipher bits as 11 ascii characters. 5231958Swnj */ 52447038Sbostic i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; 52547038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 52647038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 52747038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 52847038Sbostic encp[0] = itoa64[i]; encp += 4; 52947038Sbostic i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; 53047038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 53147038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53247038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53347038Sbostic encp[0] = itoa64[i]; encp += 4; 53447038Sbostic i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 53547038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53647038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53747038Sbostic encp[0] = itoa64[i]; 53847038Sbostic 53947038Sbostic encp[3] = 0; 54048484Sbostic 54147038Sbostic return(cryptresult); 54247038Sbostic } 54347038Sbostic 54447038Sbostic 54547038Sbostic /* 54647038Sbostic * The Key Schedule, filled in by des_setkey() or setkey(). 54747038Sbostic */ 54847038Sbostic #define KS_SIZE 16 54947038Sbostic static C_block KS[KS_SIZE]; 55047038Sbostic 55147038Sbostic /* 55247038Sbostic * Set up the key schedule from the key. 55347038Sbostic */ 55447038Sbostic des_setkey(key) 55547038Sbostic register const char *key; 55647038Sbostic { 55747038Sbostic register DCL_BLOCK(K, K0, K1); 55847038Sbostic register C_block *ptabp; 55947038Sbostic register int i; 56047038Sbostic static int des_ready = 0; 56147038Sbostic 56247038Sbostic if (!des_ready) { 56347038Sbostic init_des(); 56447038Sbostic des_ready = 1; 5651958Swnj } 56617337Sralph 56747038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); 56847038Sbostic key = (char *)&KS[0]; 56947038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 57047038Sbostic for (i = 1; i < 16; i++) { 57147038Sbostic key += sizeof(C_block); 57247038Sbostic STORE(K,K0,K1,*(C_block *)key); 57347038Sbostic ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 57447038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,ptabp); 57547038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 57647038Sbostic } 577*49804Sbostic return(0); 5781958Swnj } 5791958Swnj 5801958Swnj /* 58147038Sbostic * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 58247038Sbostic * iterations of DES, using the the given 24-bit salt and the pre-computed key 58347038Sbostic * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 58447038Sbostic * 58547038Sbostic * NOTE: the performance of this routine is critically dependent on your 58647038Sbostic * compiler and machine architecture. 5871958Swnj */ 58847038Sbostic des_cipher(in, out, salt, num_iter) 58947038Sbostic const char *in; 59047038Sbostic char *out; 59148484Sbostic long salt; 59247038Sbostic int num_iter; 59347038Sbostic { 59447038Sbostic /* variables that we want in registers, most important first */ 59547038Sbostic #if defined(pdp11) 59647038Sbostic register int j; 59747038Sbostic #endif 59847038Sbostic register long L0, L1, R0, R1, k; 59947038Sbostic register C_block *kp; 60047038Sbostic register int ks_inc, loop_count; 60147038Sbostic C_block B; 6021958Swnj 60347038Sbostic L0 = salt; 60447038Sbostic TO_SIX_BIT(salt, L0); /* convert to 8*(6+2) format */ 6051958Swnj 60647038Sbostic #if defined(vax) || defined(pdp11) 60747038Sbostic salt = ~salt; /* "x &~ y" is faster than "x & y". */ 60847038Sbostic #define SALT (~salt) 60947038Sbostic #else 61047038Sbostic #define SALT salt 61147038Sbostic #endif 6121958Swnj 61347038Sbostic #if defined(MUST_ALIGN) 61447038Sbostic B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 61547038Sbostic B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 61647038Sbostic LOAD(L,L0,L1,B); 61747038Sbostic #else 61847038Sbostic LOAD(L,L0,L1,*(C_block *)in); 61947038Sbostic #endif 62047038Sbostic LOADREG(R,R0,R1,L,L0,L1); 62147038Sbostic L0 &= 0x55555555L; 62247038Sbostic L1 &= 0x55555555L; 62347038Sbostic L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ 62447038Sbostic R0 &= 0xaaaaaaaaL; 62547038Sbostic R1 = (R1 >> 1) & 0x55555555L; 62647038Sbostic L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 62747038Sbostic STORE(L,L0,L1,B); 62847038Sbostic PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 62947038Sbostic PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 6301958Swnj 63147038Sbostic if (num_iter >= 0) 63247038Sbostic { /* encryption */ 63347038Sbostic kp = &KS[0]; 63447038Sbostic ks_inc = sizeof(*kp); 63547038Sbostic } 63647038Sbostic else 63747038Sbostic { /* decryption */ 63847038Sbostic num_iter = -num_iter; 63947038Sbostic kp = &KS[KS_SIZE-1]; 64047038Sbostic ks_inc = -sizeof(*kp); 64147038Sbostic } 6421958Swnj 64347038Sbostic while (--num_iter >= 0) { 64447038Sbostic loop_count = 8; 64547038Sbostic do { 6461958Swnj 64747038Sbostic #define BTAB(i) (((unsigned char *)&B.b[0])[i]) 64847038Sbostic #define SPTAB(t, i) (*(long *)((unsigned char *)t \ 64947038Sbostic + i*(sizeof(long)/4))) 65047038Sbostic #if defined(gould) 65147038Sbostic /* use this if BTAB(i) is evaluated just once ... */ 65247038Sbostic #define DOXOR(a,b,i) a^=SPTAB(SPE[0][i],BTAB(i));b^=SPTAB(SPE[1][i],BTAB(i)); 65347038Sbostic #else 65447038Sbostic #if defined(pdp11) 65547038Sbostic /* use this if your "long" int indexing is slow */ 65647038Sbostic #define DOXOR(a,b,i) j=BTAB(i); a^=SPTAB(SPE[0][i],j); b^=SPTAB(SPE[1][i],j); 65747038Sbostic #else 65847038Sbostic /* use this if "k" is allocated to a register ... */ 65947038Sbostic #define DOXOR(a,b,i) k=BTAB(i); a^=SPTAB(SPE[0][i],k); b^=SPTAB(SPE[1][i],k); 66047038Sbostic #endif 66147038Sbostic #endif 6621958Swnj 66347038Sbostic #define CRUNCH(L0, L1, R0, R1) \ 66447038Sbostic k = (R0 ^ R1) & SALT; \ 66547038Sbostic B.b32.i0 = k ^ R0 ^ kp->b32.i0; \ 66647038Sbostic B.b32.i1 = k ^ R1 ^ kp->b32.i1; \ 66747038Sbostic kp = (C_block *)((char *)kp+ks_inc); \ 66847038Sbostic \ 66947038Sbostic DOXOR(L0, L1, 0); \ 67047038Sbostic DOXOR(L0, L1, 1); \ 67147038Sbostic DOXOR(L0, L1, 2); \ 67247038Sbostic DOXOR(L0, L1, 3); \ 67347038Sbostic DOXOR(L0, L1, 4); \ 67447038Sbostic DOXOR(L0, L1, 5); \ 67547038Sbostic DOXOR(L0, L1, 6); \ 67647038Sbostic DOXOR(L0, L1, 7); 6771958Swnj 67847038Sbostic CRUNCH(L0, L1, R0, R1); 67947038Sbostic CRUNCH(R0, R1, L0, L1); 68047038Sbostic } while (--loop_count != 0); 68147038Sbostic kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 6821958Swnj 6831958Swnj 68447038Sbostic /* swap L and R */ 68547038Sbostic L0 ^= R0; L1 ^= R1; 68647038Sbostic R0 ^= L0; R1 ^= L1; 68747038Sbostic L0 ^= R0; L1 ^= R1; 68847038Sbostic } 6891958Swnj 69047038Sbostic /* store the encrypted (or decrypted) result */ 69147038Sbostic L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); 69247038Sbostic L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); 69347038Sbostic STORE(L,L0,L1,B); 69447038Sbostic PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 69547038Sbostic #if defined(MUST_ALIGN) 69647038Sbostic STORE(L,L0,L1,B); 69747038Sbostic out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 69847038Sbostic out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 69947038Sbostic #else 70047038Sbostic STORE(L,L0,L1,*(C_block *)out); 70147038Sbostic #endif 702*49804Sbostic return(0); 70347038Sbostic } 70447038Sbostic 70547038Sbostic 7061958Swnj /* 70747038Sbostic * Initialize various tables. This need only be done once. It could even be 70847038Sbostic * done at compile time, if the compiler were capable of that sort of thing. 7091958Swnj */ 71047038Sbostic STATIC 71147038Sbostic init_des() 7121958Swnj { 71347038Sbostic register int i, j; 71447038Sbostic register long k; 71547038Sbostic register int tableno; 71647038Sbostic static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 7171958Swnj 7181958Swnj /* 71947038Sbostic * table that converts chars "./0-9A-Za-z"to integers 0-63. 7201958Swnj */ 72147038Sbostic for (i = 0; i < 64; i++) 72247038Sbostic a64toi[itoa64[i]] = i; 72347038Sbostic 7241958Swnj /* 72547038Sbostic * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 7261958Swnj */ 72747038Sbostic for (i = 0; i < 64; i++) 72847038Sbostic perm[i] = 0; 72947038Sbostic for (i = 0; i < 64; i++) { 73047038Sbostic if ((k = PC2[i]) == 0) 73147038Sbostic continue; 73247038Sbostic k += Rotates[0]-1; 73347038Sbostic if ((k%28) < Rotates[0]) k -= 28; 73447038Sbostic k = PC1[k]; 73547038Sbostic if (k > 0) { 73647038Sbostic k--; 73747038Sbostic k = (k|07) - (k&07); 73847038Sbostic k++; 7391958Swnj } 74047038Sbostic perm[i] = k; 7411958Swnj } 74247038Sbostic #ifdef DEBUG 74347038Sbostic prtab("pc1tab", perm, 8); 74447038Sbostic #endif 74548484Sbostic init_perm(PC1ROT, perm, 8, 8); 74647038Sbostic 7471958Swnj /* 74847038Sbostic * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 7491958Swnj */ 75047038Sbostic for (j = 0; j < 2; j++) { 75147038Sbostic unsigned char pc2inv[64]; 75247038Sbostic for (i = 0; i < 64; i++) 75347038Sbostic perm[i] = pc2inv[i] = 0; 75447038Sbostic for (i = 0; i < 64; i++) { 75547038Sbostic if ((k = PC2[i]) == 0) 75647038Sbostic continue; 75747038Sbostic pc2inv[k-1] = i+1; 75847038Sbostic } 75947038Sbostic for (i = 0; i < 64; i++) { 76047038Sbostic if ((k = PC2[i]) == 0) 76147038Sbostic continue; 76247038Sbostic k += j; 76347038Sbostic if ((k%28) <= j) k -= 28; 76447038Sbostic perm[i] = pc2inv[k]; 76547038Sbostic } 76647038Sbostic #ifdef DEBUG 76747038Sbostic prtab("pc2tab", perm, 8); 76847038Sbostic #endif 76948484Sbostic init_perm(PC2ROT[j], perm, 8, 8); 7701958Swnj } 77147038Sbostic 7721958Swnj /* 77347038Sbostic * Bit reverse, then initial permutation, then expansion. 7741958Swnj */ 77547038Sbostic for (i = 0; i < 8; i++) { 77647038Sbostic for (j = 0; j < 8; j++) { 77747038Sbostic k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 77847038Sbostic if (k > 32) 77947038Sbostic k -= 32; 78047038Sbostic else if (k > 0) 78147038Sbostic k--; 78247038Sbostic if (k > 0) { 78347038Sbostic k--; 78447038Sbostic k = (k|07) - (k&07); 78547038Sbostic k++; 78647038Sbostic } 78747038Sbostic perm[i*8+j] = k; 78847038Sbostic } 78947038Sbostic } 79047038Sbostic #ifdef DEBUG 79147038Sbostic prtab("ietab", perm, 8); 79247038Sbostic #endif 79348484Sbostic init_perm(IE3264, perm, 4, 8); 79447038Sbostic 79547038Sbostic /* 79647038Sbostic * Compression, then final permutation, then bit reverse. 79747038Sbostic */ 79847038Sbostic for (i = 0; i < 64; i++) { 79947038Sbostic k = IP[CIFP[i]-1]; 80047038Sbostic if (k > 0) { 80147038Sbostic k--; 80247038Sbostic k = (k|07) - (k&07); 80347038Sbostic k++; 80447038Sbostic } 80547038Sbostic perm[k-1] = i+1; 80647038Sbostic } 80747038Sbostic #ifdef DEBUG 80847038Sbostic prtab("cftab", perm, 8); 80947038Sbostic #endif 81048484Sbostic init_perm(CF6464, perm, 8, 8); 81147038Sbostic 81247038Sbostic /* 81347038Sbostic * SPE table 81447038Sbostic */ 81547038Sbostic for (i = 0; i < 48; i++) 81647038Sbostic perm[i] = P32Tr[ExpandTr[i]-1]; 81747038Sbostic for (tableno = 0; tableno < 8; tableno++) { 81847038Sbostic for (j = 0; j < 64; j++) { 81947038Sbostic k = (((j >> 0) &01) << 5)| 82047038Sbostic (((j >> 1) &01) << 3)| 82147038Sbostic (((j >> 2) &01) << 2)| 82247038Sbostic (((j >> 3) &01) << 1)| 82347038Sbostic (((j >> 4) &01) << 0)| 82447038Sbostic (((j >> 5) &01) << 4); 82547038Sbostic k = S[tableno][k]; 82647038Sbostic k = (((k >> 3)&01) << 0)| 82747038Sbostic (((k >> 2)&01) << 1)| 82847038Sbostic (((k >> 1)&01) << 2)| 82947038Sbostic (((k >> 0)&01) << 3); 83047038Sbostic for (i = 0; i < 32; i++) 83147038Sbostic tmp32[i] = 0; 83247038Sbostic for (i = 0; i < 4; i++) 83347038Sbostic tmp32[4 * tableno + i] = (k >> i) & 01; 83447038Sbostic k = 0; 83547038Sbostic for (i = 24; --i >= 0; ) 83647038Sbostic k = (k<<1) | tmp32[perm[i]-1]; 83747038Sbostic TO_SIX_BIT(SPE[0][tableno][j], k); 83847038Sbostic k = 0; 83947038Sbostic for (i = 24; --i >= 0; ) 84047038Sbostic k = (k<<1) | tmp32[perm[i+24]-1]; 84147038Sbostic TO_SIX_BIT(SPE[1][tableno][j], k); 84247038Sbostic } 84347038Sbostic } 8441958Swnj } 8451958Swnj 84647038Sbostic /* 84748484Sbostic * Initialize "perm" to represent transformation "p", which rearranges 84848484Sbostic * (perhaps with expansion and/or contraction) one packed array of bits 84948484Sbostic * (of size "chars_in" characters) into another array (of size "chars_out" 85048484Sbostic * characters). 85148484Sbostic * 85247038Sbostic * "perm" must be all-zeroes on entry to this routine. 85347038Sbostic */ 85447038Sbostic STATIC 85548484Sbostic init_perm(perm, p, chars_in, chars_out) 85647038Sbostic C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; 85747038Sbostic unsigned char p[64]; 85847038Sbostic int chars_in, chars_out; 8591958Swnj { 86047038Sbostic register int i, j, k, l; 86117337Sralph 86247038Sbostic for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 86347038Sbostic l = p[k] - 1; /* where this bit comes from */ 86447038Sbostic if (l < 0) 86547038Sbostic continue; /* output bit is always 0 */ 86647038Sbostic i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 86747038Sbostic l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 86847038Sbostic for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 86947038Sbostic if ((j & l) != 0) 87047038Sbostic perm[i][j].b[k>>3] |= 1<<(k&07); 87147038Sbostic } 8721958Swnj } 87347038Sbostic } 8741958Swnj 87547038Sbostic /* 87647038Sbostic * "setkey" routine (for backwards compatibility) 87747038Sbostic */ 87847038Sbostic setkey(key) 87947038Sbostic register const char *key; 88047038Sbostic { 88147038Sbostic register int i, j, k; 88247038Sbostic C_block keyblock; 88347038Sbostic 88447038Sbostic for (i = 0; i < 8; i++) { 88547038Sbostic k = 0; 88647038Sbostic for (j = 0; j < 8; j++) { 88747038Sbostic k <<= 1; 88847038Sbostic k |= (unsigned char)*key++; 8891958Swnj } 89047038Sbostic keyblock.b[i] = k; 8911958Swnj } 892*49804Sbostic return(des_setkey((char *)keyblock.b)); 8931958Swnj } 89447038Sbostic 89547038Sbostic /* 89647038Sbostic * "encrypt" routine (for backwards compatibility) 89747038Sbostic */ 89847038Sbostic encrypt(block, flag) 89947038Sbostic register char *block; 90047038Sbostic int flag; 90147038Sbostic { 90247038Sbostic register int i, j, k; 90347038Sbostic C_block cblock; 90447038Sbostic 90547038Sbostic for (i = 0; i < 8; i++) { 90647038Sbostic k = 0; 90747038Sbostic for (j = 0; j < 8; j++) { 90847038Sbostic k <<= 1; 90947038Sbostic k |= (unsigned char)*block++; 91047038Sbostic } 91147038Sbostic cblock.b[i] = k; 91247038Sbostic } 913*49804Sbostic if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) 914*49804Sbostic return(1); 91547038Sbostic for (i = 7; i >= 0; i--) { 91647038Sbostic k = cblock.b[i]; 91747038Sbostic for (j = 7; j >= 0; j--) { 91847038Sbostic *--block = k&01; 91947038Sbostic k >>= 1; 92047038Sbostic } 92147038Sbostic } 922*49804Sbostic return(0); 92347038Sbostic } 92447038Sbostic 92547038Sbostic #ifdef DEBUG 92647038Sbostic STATIC 92747038Sbostic prtab(s, t, num_rows) 92847038Sbostic char *s; 92947038Sbostic unsigned char *t; 93047038Sbostic int num_rows; 93147038Sbostic { 93247038Sbostic register int i, j; 93347038Sbostic 93448485Sbostic (void)printf("%s:\n", s); 93547038Sbostic for (i = 0; i < num_rows; i++) { 93647038Sbostic for (j = 0; j < 8; j++) { 93748485Sbostic (void)printf("%3d", t[i*8+j]); 93847038Sbostic } 93948485Sbostic (void)printf("\n"); 94047038Sbostic } 94148485Sbostic (void)printf("\n"); 94247038Sbostic } 94347038Sbostic #endif 944