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*50127Skarels static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 06/25/91"; 1347038Sbostic #endif /* LIBC_SCCS and not lint */ 1422083Smckusick 1546597Sdonn #include <unistd.h> 1649831Sbostic #include <limits.h> 1748485Sbostic #include <pwd.h> 1846597Sdonn 191958Swnj /* 2047038Sbostic * UNIX password, and DES, encryption. 2147038Sbostic * By Tom Truscott, trt@rti.rti.org, 2247038Sbostic * from algorithms by Robert W. Baldwin and James Gillogly. 2347038Sbostic * 2447038Sbostic * References: 2547038Sbostic * "Mathematical Cryptology for Computer Scientists and Mathematicians," 2647038Sbostic * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 2747038Sbostic * 2847038Sbostic * "Password Security: A Case History," R. Morris and Ken Thompson, 2947038Sbostic * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 3047038Sbostic * 3147038Sbostic * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 3247038Sbostic * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 331958Swnj */ 341958Swnj 3547038Sbostic /* ===== Configuration ==================== */ 3647038Sbostic 371958Swnj /* 3847038Sbostic * define "MUST_ALIGN" if your compiler cannot load/store 3947038Sbostic * long integers at arbitrary (e.g. odd) memory locations. 4047038Sbostic * (Either that or never pass unaligned addresses to des_cipher!) 411958Swnj */ 4247038Sbostic #if !defined(vax) 4347038Sbostic #define MUST_ALIGN 4447038Sbostic #endif 451958Swnj 4649831Sbostic #ifdef CHAR_BITS 4749831Sbostic #if CHAR_BITS != 8 4849831Sbostic #error C_block structure assumes 8 bit characters 4949831Sbostic #endif 5049831Sbostic #endif 5149831Sbostic 521958Swnj /* 5347038Sbostic * define "LONG_IS_32_BITS" only if sizeof(long)==4. 5447038Sbostic * This avoids use of bit fields (your compiler may be sloppy with them). 551958Swnj */ 5647038Sbostic #if !defined(cray) 5747038Sbostic #define LONG_IS_32_BITS 5847038Sbostic #endif 591958Swnj 601958Swnj /* 6147038Sbostic * define "B64" to be the declaration for a 64 bit integer. 6247038Sbostic * XXX this feature is currently unused, see "endian" comment below. 631958Swnj */ 6447038Sbostic #if defined(cray) 6547038Sbostic #define B64 long 6647038Sbostic #endif 6747038Sbostic #if defined(convex) 6847038Sbostic #define B64 long long 6947038Sbostic #endif 701958Swnj 711958Swnj /* 7247038Sbostic * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 7347038Sbostic * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 7448484Sbostic * little effect on crypt(). 751958Swnj */ 7647038Sbostic #if defined(notdef) 7747038Sbostic #define LARGEDATA 7847038Sbostic #endif 791958Swnj 8048484Sbostic /* compile with "-DSTATIC=int" when profiling */ 8148484Sbostic #ifndef STATIC 8247038Sbostic #define STATIC static 8348484Sbostic #endif 8448484Sbostic STATIC init_des(), init_perm(), permute(); 8547038Sbostic #ifdef DEBUG 8647038Sbostic STATIC prtab(); 8747038Sbostic #endif 881958Swnj 8947038Sbostic /* ==================================== */ 9047038Sbostic 911958Swnj /* 9247038Sbostic * Cipher-block representation (Bob Baldwin): 9347038Sbostic * 9447038Sbostic * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 9547038Sbostic * representation is to store one bit per byte in an array of bytes. Bit N of 9647038Sbostic * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 9747038Sbostic * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 9847038Sbostic * first byte, 9..16 in the second, and so on. The DES spec apparently has 9947038Sbostic * bit 1 in the MSB of the first byte, but that is particularly noxious so we 10047038Sbostic * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 10147038Sbostic * the MSB of the first byte. Specifically, the 64-bit input data and key are 10247038Sbostic * converted to LSB format, and the output 64-bit block is converted back into 10347038Sbostic * MSB format. 10447038Sbostic * 10547038Sbostic * DES operates internally on groups of 32 bits which are expanded to 48 bits 10647038Sbostic * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 10747038Sbostic * the computation, the expansion is applied only once, the expanded 10847038Sbostic * representation is maintained during the encryption, and a compression 10947038Sbostic * permutation is applied only at the end. To speed up the S-box lookups, 11047038Sbostic * the 48 bits are maintained as eight 6 bit groups, one per byte, which 11147038Sbostic * directly feed the eight S-boxes. Within each byte, the 6 bits are the 11247038Sbostic * most significant ones. The low two bits of each byte are zero. (Thus, 11347038Sbostic * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 11447038Sbostic * first byte in the eight byte representation, bit 2 of the 48 bit value is 11548484Sbostic * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 11647038Sbostic * used, in which the output is the 64 bit result of an S-box lookup which 11747038Sbostic * has been permuted by P and expanded by E, and is ready for use in the next 11847038Sbostic * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 11947038Sbostic * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 12047038Sbostic * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 12147038Sbostic * "salt" are also converted to this 8*(6+2) format. The SPE table size is 12247038Sbostic * 8*64*8 = 4K bytes. 12347038Sbostic * 12447038Sbostic * To speed up bit-parallel operations (such as XOR), the 8 byte 12547038Sbostic * representation is "union"ed with 32 bit values "i0" and "i1", and, on 12647038Sbostic * machines which support it, a 64 bit value "b64". This data structure, 12747038Sbostic * "C_block", has two problems. First, alignment restrictions must be 12847038Sbostic * honored. Second, the byte-order (e.g. little-endian or big-endian) of 12947038Sbostic * the architecture becomes visible. 13047038Sbostic * 13147038Sbostic * The byte-order problem is unfortunate, since on the one hand it is good 13247038Sbostic * to have a machine-independent C_block representation (bits 1..8 in the 13347038Sbostic * first byte, etc.), and on the other hand it is good for the LSB of the 13447038Sbostic * first byte to be the LSB of i0. We cannot have both these things, so we 13547038Sbostic * currently use the "little-endian" representation and avoid any multi-byte 13647038Sbostic * operations that depend on byte order. This largely precludes use of the 13747038Sbostic * 64-bit datatype since the relative order of i0 and i1 are unknown. It 13847038Sbostic * also inhibits grouping the SPE table to look up 12 bits at a time. (The 13947038Sbostic * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 14048484Sbostic * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 14147038Sbostic * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 14247038Sbostic * requires a 128 kilobyte table, so perhaps this is not a big loss. 14347038Sbostic * 14447038Sbostic * Permutation representation (Jim Gillogly): 14547038Sbostic * 14647038Sbostic * A transformation is defined by its effect on each of the 8 bytes of the 14747038Sbostic * 64-bit input. For each byte we give a 64-bit output that has the bits in 14847038Sbostic * the input distributed appropriately. The transformation is then the OR 14947038Sbostic * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 15047038Sbostic * each transformation. Unless LARGEDATA is defined, however, a more compact 15147038Sbostic * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 15247038Sbostic * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 15347038Sbostic * is slower but tolerable, particularly for password encryption in which 15447038Sbostic * the SPE transformation is iterated many times. The small tables total 9K 15547038Sbostic * bytes, the large tables total 72K bytes. 15647038Sbostic * 15747038Sbostic * The transformations used are: 15847038Sbostic * IE3264: MSB->LSB conversion, initial permutation, and expansion. 15947038Sbostic * This is done by collecting the 32 even-numbered bits and applying 16047038Sbostic * a 32->64 bit transformation, and then collecting the 32 odd-numbered 16147038Sbostic * bits and applying the same transformation. Since there are only 16247038Sbostic * 32 input bits, the IE3264 transformation table is half the size of 16347038Sbostic * the usual table. 16447038Sbostic * CF6464: Compression, final permutation, and LSB->MSB conversion. 16547038Sbostic * This is done by two trivial 48->32 bit compressions to obtain 16647038Sbostic * a 64-bit block (the bit numbering is given in the "CIFP" table) 16747038Sbostic * followed by a 64->64 bit "cleanup" transformation. (It would 16847038Sbostic * be possible to group the bits in the 64-bit block so that 2 16947038Sbostic * identical 32->32 bit transformations could be used instead, 17047038Sbostic * saving a factor of 4 in space and possibly 2 in time, but 17147038Sbostic * byte-ordering and other complications rear their ugly head. 17247038Sbostic * Similar opportunities/problems arise in the key schedule 17347038Sbostic * transforms.) 17447038Sbostic * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 17547038Sbostic * This admittedly baroque 64->64 bit transformation is used to 17647038Sbostic * produce the first code (in 8*(6+2) format) of the key schedule. 17747038Sbostic * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 17847038Sbostic * It would be possible to define 15 more transformations, each 17947038Sbostic * with a different rotation, to generate the entire key schedule. 18047038Sbostic * To save space, however, we instead permute each code into the 18147038Sbostic * next by using a transformation that "undoes" the PC2 permutation, 18247038Sbostic * rotates the code, and then applies PC2. Unfortunately, PC2 18347038Sbostic * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 18447038Sbostic * invertible. We get around that problem by using a modified PC2 18547038Sbostic * which retains the 8 otherwise-lost bits in the unused low-order 18647038Sbostic * bits of each byte. The low-order bits are cleared when the 18747038Sbostic * codes are stored into the key schedule. 18847038Sbostic * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 18947038Sbostic * This is faster than applying PC2ROT[0] twice, 19047038Sbostic * 19147038Sbostic * The Bell Labs "salt" (Bob Baldwin): 19247038Sbostic * 19347038Sbostic * The salting is a simple permutation applied to the 48-bit result of E. 19447038Sbostic * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 19547038Sbostic * i+24 of the result are swapped. The salt is thus a 24 bit number, with 19647038Sbostic * 16777216 possible values. (The original salt was 12 bits and could not 19747038Sbostic * swap bits 13..24 with 36..48.) 19847038Sbostic * 19948484Sbostic * It is possible, but ugly, to warp the SPE table to account for the salt 20048484Sbostic * permutation. Fortunately, the conditional bit swapping requires only 20148484Sbostic * about four machine instructions and can be done on-the-fly with about an 20248484Sbostic * 8% performance penalty. 2031958Swnj */ 20448484Sbostic 20547038Sbostic typedef union { 20647038Sbostic unsigned char b[8]; 20747038Sbostic struct { 20847038Sbostic #if defined(LONG_IS_32_BITS) 20947038Sbostic /* long is often faster than a 32-bit bit field */ 21047038Sbostic long i0; 21147038Sbostic long i1; 21247038Sbostic #else 21347038Sbostic long i0: 32; 21447038Sbostic long i1: 32; 21547038Sbostic #endif 21647038Sbostic } b32; 21747038Sbostic #if defined(B64) 21847038Sbostic B64 b64; 21947038Sbostic #endif 22047038Sbostic } C_block; 2211958Swnj 2221958Swnj /* 22347038Sbostic * Convert twenty-four-bit long in host-order 22447038Sbostic * to six bits (and 2 low-order zeroes) per char little-endian format. 2251958Swnj */ 22647038Sbostic #define TO_SIX_BIT(rslt, src) { \ 22747038Sbostic C_block cvt; \ 22847038Sbostic cvt.b[0] = src; src >>= 6; \ 22947038Sbostic cvt.b[1] = src; src >>= 6; \ 23047038Sbostic cvt.b[2] = src; src >>= 6; \ 23147038Sbostic cvt.b[3] = src; \ 23247038Sbostic rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 23347038Sbostic } 2341958Swnj 2351958Swnj /* 23647038Sbostic * These macros may someday permit efficient use of 64-bit integers. 23717337Sralph */ 23847038Sbostic #define ZERO(d,d0,d1) d0 = 0, d1 = 0 23947038Sbostic #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 24047038Sbostic #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 24147038Sbostic #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 24247038Sbostic #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 24347038Sbostic #define DCL_BLOCK(d,d0,d1) long d0, d1 24447038Sbostic 24547038Sbostic #if defined(LARGEDATA) 24647038Sbostic /* Waste memory like crazy. Also, do permutations in line */ 24747038Sbostic #define LGCHUNKBITS 3 24847038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 24947038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 25047038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 25147038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 25247038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 25347038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \ 25447038Sbostic OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 25547038Sbostic OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 25647038Sbostic OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 25747038Sbostic OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 25847038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 25947038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 26047038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 26147038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 26247038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 26347038Sbostic #else 26447038Sbostic /* "small data" */ 26547038Sbostic #define LGCHUNKBITS 2 26647038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 26747038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 26847038Sbostic { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 26947038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 27047038Sbostic { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 27147038Sbostic 27247038Sbostic STATIC 27347038Sbostic permute(cp, out, p, chars_in) 27447038Sbostic unsigned char *cp; 27547038Sbostic C_block *out; 27647038Sbostic register C_block *p; 27747038Sbostic int chars_in; 27847038Sbostic { 27947038Sbostic register DCL_BLOCK(D,D0,D1); 28047038Sbostic register C_block *tp; 28147038Sbostic register int t; 28247038Sbostic 28347038Sbostic ZERO(D,D0,D1); 28447038Sbostic do { 28547038Sbostic t = *cp++; 28647038Sbostic tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 28747038Sbostic tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 28847038Sbostic } while (--chars_in > 0); 28947038Sbostic STORE(D,D0,D1,*out); 29047038Sbostic } 29147038Sbostic #endif /* LARGEDATA */ 29247038Sbostic 29347038Sbostic 29447038Sbostic /* ===== (mostly) Standard DES Tables ==================== */ 29547038Sbostic 29647038Sbostic static unsigned char IP[] = { /* initial permutation */ 29747038Sbostic 58, 50, 42, 34, 26, 18, 10, 2, 29847038Sbostic 60, 52, 44, 36, 28, 20, 12, 4, 29947038Sbostic 62, 54, 46, 38, 30, 22, 14, 6, 30047038Sbostic 64, 56, 48, 40, 32, 24, 16, 8, 30147038Sbostic 57, 49, 41, 33, 25, 17, 9, 1, 30247038Sbostic 59, 51, 43, 35, 27, 19, 11, 3, 30347038Sbostic 61, 53, 45, 37, 29, 21, 13, 5, 30447038Sbostic 63, 55, 47, 39, 31, 23, 15, 7, 30517337Sralph }; 30617337Sralph 30747038Sbostic /* The final permutation is the inverse of IP - no table is necessary */ 30847038Sbostic 30947038Sbostic static unsigned char ExpandTr[] = { /* expansion operation */ 31047038Sbostic 32, 1, 2, 3, 4, 5, 31147038Sbostic 4, 5, 6, 7, 8, 9, 31247038Sbostic 8, 9, 10, 11, 12, 13, 31347038Sbostic 12, 13, 14, 15, 16, 17, 31447038Sbostic 16, 17, 18, 19, 20, 21, 31547038Sbostic 20, 21, 22, 23, 24, 25, 31647038Sbostic 24, 25, 26, 27, 28, 29, 31747038Sbostic 28, 29, 30, 31, 32, 1, 31847038Sbostic }; 31947038Sbostic 32049831Sbostic static unsigned char PC1[] = { /* permuted choice table 1 */ 32147038Sbostic 57, 49, 41, 33, 25, 17, 9, 32247038Sbostic 1, 58, 50, 42, 34, 26, 18, 32347038Sbostic 10, 2, 59, 51, 43, 35, 27, 32447038Sbostic 19, 11, 3, 60, 52, 44, 36, 32547038Sbostic 32647038Sbostic 63, 55, 47, 39, 31, 23, 15, 32747038Sbostic 7, 62, 54, 46, 38, 30, 22, 32847038Sbostic 14, 6, 61, 53, 45, 37, 29, 32947038Sbostic 21, 13, 5, 28, 20, 12, 4, 33047038Sbostic }; 33147038Sbostic 33249831Sbostic static unsigned char Rotates[] = { /* PC1 rotation schedule */ 33347038Sbostic 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 33447038Sbostic }; 33547038Sbostic 33647038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 33749831Sbostic static unsigned char PC2[] = { /* permuted choice table 2 */ 33847038Sbostic 9, 18, 14, 17, 11, 24, 1, 5, 33947038Sbostic 22, 25, 3, 28, 15, 6, 21, 10, 34047038Sbostic 35, 38, 23, 19, 12, 4, 26, 8, 34147038Sbostic 43, 54, 16, 7, 27, 20, 13, 2, 34247038Sbostic 34347038Sbostic 0, 0, 41, 52, 31, 37, 47, 55, 34447038Sbostic 0, 0, 30, 40, 51, 45, 33, 48, 34547038Sbostic 0, 0, 44, 49, 39, 56, 34, 53, 34647038Sbostic 0, 0, 46, 42, 50, 36, 29, 32, 34747038Sbostic }; 34847038Sbostic 34947038Sbostic static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 35047038Sbostic /* S[1] */ 35147038Sbostic 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 35247038Sbostic 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 35347038Sbostic 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 35447038Sbostic 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 35547038Sbostic /* S[2] */ 35647038Sbostic 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 35747038Sbostic 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 35847038Sbostic 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 35947038Sbostic 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 36047038Sbostic /* S[3] */ 36147038Sbostic 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 36247038Sbostic 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 36347038Sbostic 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 36447038Sbostic 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 36547038Sbostic /* S[4] */ 36647038Sbostic 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 36747038Sbostic 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 36847038Sbostic 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 36947038Sbostic 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 37047038Sbostic /* S[5] */ 37147038Sbostic 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 37247038Sbostic 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 37347038Sbostic 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 37447038Sbostic 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 37547038Sbostic /* S[6] */ 37647038Sbostic 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 37747038Sbostic 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 37847038Sbostic 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 37947038Sbostic 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 38047038Sbostic /* S[7] */ 38147038Sbostic 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 38247038Sbostic 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 38347038Sbostic 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 38447038Sbostic 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 38547038Sbostic /* S[8] */ 38647038Sbostic 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 38747038Sbostic 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 38847038Sbostic 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 38947038Sbostic 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 39047038Sbostic }; 39147038Sbostic 39247038Sbostic static unsigned char P32Tr[] = { /* 32-bit permutation function */ 39347038Sbostic 16, 7, 20, 21, 39447038Sbostic 29, 12, 28, 17, 39547038Sbostic 1, 15, 23, 26, 39647038Sbostic 5, 18, 31, 10, 39747038Sbostic 2, 8, 24, 14, 39847038Sbostic 32, 27, 3, 9, 39947038Sbostic 19, 13, 30, 6, 40047038Sbostic 22, 11, 4, 25, 40147038Sbostic }; 40247038Sbostic 40347038Sbostic static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 40447038Sbostic 1, 2, 3, 4, 17, 18, 19, 20, 40547038Sbostic 5, 6, 7, 8, 21, 22, 23, 24, 40647038Sbostic 9, 10, 11, 12, 25, 26, 27, 28, 40747038Sbostic 13, 14, 15, 16, 29, 30, 31, 32, 40847038Sbostic 40947038Sbostic 33, 34, 35, 36, 49, 50, 51, 52, 41047038Sbostic 37, 38, 39, 40, 53, 54, 55, 56, 41147038Sbostic 41, 42, 43, 44, 57, 58, 59, 60, 41247038Sbostic 45, 46, 47, 48, 61, 62, 63, 64, 41347038Sbostic }; 41447038Sbostic 41547038Sbostic static unsigned char itoa64[] = /* 0..63 => ascii-64 */ 41647038Sbostic "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 41747038Sbostic 41847038Sbostic 41947038Sbostic /* ===== Tables that are initialized at run time ==================== */ 42047038Sbostic 42147038Sbostic 42247038Sbostic static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ 42347038Sbostic 42447038Sbostic /* Initial key schedule permutation */ 42547038Sbostic static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 42647038Sbostic 42747038Sbostic /* Subsequent key schedule rotation permutations */ 42847038Sbostic static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 42947038Sbostic 43047038Sbostic /* Initial permutation/expansion table */ 43147038Sbostic static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 43247038Sbostic 43347038Sbostic /* Table that combines the S, P, and E operations. */ 43447038Sbostic static long SPE[2][8][64]; 43547038Sbostic 43647038Sbostic /* compressed/interleaved => final permutation table */ 43747038Sbostic static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 43847038Sbostic 43947038Sbostic 44047038Sbostic /* ==================================== */ 44147038Sbostic 44247038Sbostic 44347038Sbostic static C_block constdatablock; /* encryption constant */ 44447038Sbostic static char cryptresult[1+4+4+11+1]; /* encrypted result */ 44547038Sbostic 44617337Sralph /* 44748484Sbostic * Return a pointer to static data consisting of the "setting" 44848484Sbostic * followed by an encryption produced by the "key" and "setting". 4491958Swnj */ 45047038Sbostic char * 45147038Sbostic crypt(key, setting) 45247038Sbostic register const char *key; 45347038Sbostic register const char *setting; 4541958Swnj { 45547038Sbostic register char *encp; 45647038Sbostic register long i; 45748484Sbostic register int t; 45847038Sbostic long salt; 45949831Sbostic int num_iter, salt_size; 46047038Sbostic C_block keyblock, rsltblock; 4611958Swnj 46248484Sbostic for (i = 0; i < 8; i++) { 46348484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 46447038Sbostic key++; 46548484Sbostic keyblock.b[i] = t; 46648484Sbostic } 46749804Sbostic if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */ 468*50127Skarels return (NULL); 46947038Sbostic 47047038Sbostic encp = &cryptresult[0]; 47148485Sbostic switch (*setting) { 47248485Sbostic case _PASSWORD_EFMT1: 47349831Sbostic /* 47449831Sbostic * Involve the rest of the password 8 characters at a time. 47549831Sbostic */ 47649831Sbostic while (*key) { 47749831Sbostic if (des_cipher((char *)&keyblock, 47849831Sbostic (char *)&keyblock, 0L, 1)) 479*50127Skarels return (NULL); 48049831Sbostic for (i = 0; i < 8; i++) { 48149831Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 48249831Sbostic key++; 48349831Sbostic keyblock.b[i] ^= t; 48449831Sbostic } 48549831Sbostic if (des_setkey((char *)keyblock.b)) 486*50127Skarels return (NULL); 48749831Sbostic } 48849831Sbostic 48947038Sbostic *encp++ = *setting++; 49047038Sbostic 49147038Sbostic /* get iteration count */ 49247038Sbostic num_iter = 0; 49347038Sbostic for (i = 4; --i >= 0; ) { 49448484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 49548484Sbostic t = '.'; 49648484Sbostic encp[i] = t; 49748484Sbostic num_iter = (num_iter<<6) | a64toi[t]; 49847038Sbostic } 49947038Sbostic setting += 4; 50047038Sbostic encp += 4; 50147038Sbostic salt_size = 4; 50248485Sbostic break; 50348485Sbostic default: 50448485Sbostic num_iter = 25; 50548485Sbostic salt_size = 2; 50647038Sbostic } 50747038Sbostic 50847038Sbostic salt = 0; 50947038Sbostic for (i = salt_size; --i >= 0; ) { 51048484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 51148484Sbostic t = '.'; 51248484Sbostic encp[i] = t; 51348484Sbostic salt = (salt<<6) | a64toi[t]; 51447038Sbostic } 51547038Sbostic encp += salt_size; 51649804Sbostic if (des_cipher((char *)&constdatablock, (char *)&rsltblock, 51749804Sbostic salt, num_iter)) 518*50127Skarels return (NULL); 51947038Sbostic 5201958Swnj /* 52147038Sbostic * Encode the 64 cipher bits as 11 ascii characters. 5221958Swnj */ 52347038Sbostic i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; 52447038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 52547038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 52647038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 52747038Sbostic encp[0] = itoa64[i]; encp += 4; 52847038Sbostic i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; 52947038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 53047038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53147038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53247038Sbostic encp[0] = itoa64[i]; encp += 4; 53347038Sbostic i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 53447038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53547038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53647038Sbostic encp[0] = itoa64[i]; 53747038Sbostic 53847038Sbostic encp[3] = 0; 53948484Sbostic 540*50127Skarels return (cryptresult); 54147038Sbostic } 54247038Sbostic 54347038Sbostic 54447038Sbostic /* 54547038Sbostic * The Key Schedule, filled in by des_setkey() or setkey(). 54647038Sbostic */ 54747038Sbostic #define KS_SIZE 16 54847038Sbostic static C_block KS[KS_SIZE]; 54947038Sbostic 55047038Sbostic /* 55147038Sbostic * Set up the key schedule from the key. 55247038Sbostic */ 55347038Sbostic des_setkey(key) 55447038Sbostic register const char *key; 55547038Sbostic { 55647038Sbostic register DCL_BLOCK(K, K0, K1); 55747038Sbostic register C_block *ptabp; 55847038Sbostic register int i; 55947038Sbostic static int des_ready = 0; 56047038Sbostic 56147038Sbostic if (!des_ready) { 56247038Sbostic init_des(); 56347038Sbostic des_ready = 1; 5641958Swnj } 56517337Sralph 56647038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); 56747038Sbostic key = (char *)&KS[0]; 56849831Sbostic STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); 56947038Sbostic for (i = 1; i < 16; i++) { 57047038Sbostic key += sizeof(C_block); 57147038Sbostic STORE(K,K0,K1,*(C_block *)key); 57247038Sbostic ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 57347038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,ptabp); 57449831Sbostic STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); 57547038Sbostic } 576*50127Skarels return (0); 5771958Swnj } 5781958Swnj 5791958Swnj /* 58047038Sbostic * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 58147038Sbostic * iterations of DES, using the the given 24-bit salt and the pre-computed key 58247038Sbostic * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 58347038Sbostic * 58447038Sbostic * NOTE: the performance of this routine is critically dependent on your 58547038Sbostic * compiler and machine architecture. 5861958Swnj */ 58747038Sbostic des_cipher(in, out, salt, num_iter) 58847038Sbostic const char *in; 58947038Sbostic char *out; 59048484Sbostic long salt; 59147038Sbostic int num_iter; 59247038Sbostic { 59347038Sbostic /* variables that we want in registers, most important first */ 59447038Sbostic #if defined(pdp11) 59547038Sbostic register int j; 59647038Sbostic #endif 59747038Sbostic register long L0, L1, R0, R1, k; 59847038Sbostic register C_block *kp; 59947038Sbostic register int ks_inc, loop_count; 60047038Sbostic C_block B; 6011958Swnj 60247038Sbostic L0 = salt; 60349831Sbostic TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ 6041958Swnj 60547038Sbostic #if defined(vax) || defined(pdp11) 60647038Sbostic salt = ~salt; /* "x &~ y" is faster than "x & y". */ 60747038Sbostic #define SALT (~salt) 60847038Sbostic #else 60947038Sbostic #define SALT salt 61047038Sbostic #endif 6111958Swnj 61247038Sbostic #if defined(MUST_ALIGN) 61347038Sbostic B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 61447038Sbostic B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 61547038Sbostic LOAD(L,L0,L1,B); 61647038Sbostic #else 61747038Sbostic LOAD(L,L0,L1,*(C_block *)in); 61847038Sbostic #endif 61947038Sbostic LOADREG(R,R0,R1,L,L0,L1); 62047038Sbostic L0 &= 0x55555555L; 62147038Sbostic L1 &= 0x55555555L; 62247038Sbostic L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ 62347038Sbostic R0 &= 0xaaaaaaaaL; 62447038Sbostic R1 = (R1 >> 1) & 0x55555555L; 62547038Sbostic L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 62647038Sbostic STORE(L,L0,L1,B); 62747038Sbostic PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 62847038Sbostic PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 6291958Swnj 63047038Sbostic if (num_iter >= 0) 63147038Sbostic { /* encryption */ 63247038Sbostic kp = &KS[0]; 63347038Sbostic ks_inc = sizeof(*kp); 63447038Sbostic } 63547038Sbostic else 63647038Sbostic { /* decryption */ 63747038Sbostic num_iter = -num_iter; 63847038Sbostic kp = &KS[KS_SIZE-1]; 63947038Sbostic ks_inc = -sizeof(*kp); 64047038Sbostic } 6411958Swnj 64247038Sbostic while (--num_iter >= 0) { 64347038Sbostic loop_count = 8; 64447038Sbostic do { 6451958Swnj 64649831Sbostic #define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4))) 64747038Sbostic #if defined(gould) 64849831Sbostic /* use this if B.b[i] is evaluated just once ... */ 64949831Sbostic #define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); 65047038Sbostic #else 65147038Sbostic #if defined(pdp11) 65247038Sbostic /* use this if your "long" int indexing is slow */ 65349831Sbostic #define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); 65447038Sbostic #else 65547038Sbostic /* use this if "k" is allocated to a register ... */ 65649831Sbostic #define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); 65747038Sbostic #endif 65847038Sbostic #endif 6591958Swnj 66049831Sbostic #define CRUNCH(p0, p1, q0, q1) \ 66149831Sbostic k = (q0 ^ q1) & SALT; \ 66249831Sbostic B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ 66349831Sbostic B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ 66447038Sbostic kp = (C_block *)((char *)kp+ks_inc); \ 66547038Sbostic \ 66649831Sbostic DOXOR(p0, p1, 0); \ 66749831Sbostic DOXOR(p0, p1, 1); \ 66849831Sbostic DOXOR(p0, p1, 2); \ 66949831Sbostic DOXOR(p0, p1, 3); \ 67049831Sbostic DOXOR(p0, p1, 4); \ 67149831Sbostic DOXOR(p0, p1, 5); \ 67249831Sbostic DOXOR(p0, p1, 6); \ 67349831Sbostic DOXOR(p0, p1, 7); 6741958Swnj 67547038Sbostic CRUNCH(L0, L1, R0, R1); 67647038Sbostic CRUNCH(R0, R1, L0, L1); 67747038Sbostic } while (--loop_count != 0); 67847038Sbostic kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 6791958Swnj 6801958Swnj 68147038Sbostic /* swap L and R */ 68247038Sbostic L0 ^= R0; L1 ^= R1; 68347038Sbostic R0 ^= L0; R1 ^= L1; 68447038Sbostic L0 ^= R0; L1 ^= R1; 68547038Sbostic } 6861958Swnj 68747038Sbostic /* store the encrypted (or decrypted) result */ 68847038Sbostic L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); 68947038Sbostic L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); 69047038Sbostic STORE(L,L0,L1,B); 69147038Sbostic PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 69247038Sbostic #if defined(MUST_ALIGN) 69347038Sbostic STORE(L,L0,L1,B); 69447038Sbostic out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 69547038Sbostic out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 69647038Sbostic #else 69747038Sbostic STORE(L,L0,L1,*(C_block *)out); 69847038Sbostic #endif 699*50127Skarels return (0); 70047038Sbostic } 70147038Sbostic 70247038Sbostic 7031958Swnj /* 70447038Sbostic * Initialize various tables. This need only be done once. It could even be 70547038Sbostic * done at compile time, if the compiler were capable of that sort of thing. 7061958Swnj */ 70747038Sbostic STATIC 70847038Sbostic init_des() 7091958Swnj { 71047038Sbostic register int i, j; 71147038Sbostic register long k; 71247038Sbostic register int tableno; 71347038Sbostic static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 7141958Swnj 7151958Swnj /* 71647038Sbostic * table that converts chars "./0-9A-Za-z"to integers 0-63. 7171958Swnj */ 71847038Sbostic for (i = 0; i < 64; i++) 71947038Sbostic a64toi[itoa64[i]] = i; 72047038Sbostic 7211958Swnj /* 72247038Sbostic * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 7231958Swnj */ 72447038Sbostic for (i = 0; i < 64; i++) 72547038Sbostic perm[i] = 0; 72647038Sbostic for (i = 0; i < 64; i++) { 72747038Sbostic if ((k = PC2[i]) == 0) 72847038Sbostic continue; 72947038Sbostic k += Rotates[0]-1; 73047038Sbostic if ((k%28) < Rotates[0]) k -= 28; 73147038Sbostic k = PC1[k]; 73247038Sbostic if (k > 0) { 73347038Sbostic k--; 73447038Sbostic k = (k|07) - (k&07); 73547038Sbostic k++; 7361958Swnj } 73747038Sbostic perm[i] = k; 7381958Swnj } 73947038Sbostic #ifdef DEBUG 74047038Sbostic prtab("pc1tab", perm, 8); 74147038Sbostic #endif 74248484Sbostic init_perm(PC1ROT, perm, 8, 8); 74347038Sbostic 7441958Swnj /* 74547038Sbostic * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 7461958Swnj */ 74747038Sbostic for (j = 0; j < 2; j++) { 74847038Sbostic unsigned char pc2inv[64]; 74947038Sbostic for (i = 0; i < 64; i++) 75047038Sbostic perm[i] = pc2inv[i] = 0; 75147038Sbostic for (i = 0; i < 64; i++) { 75247038Sbostic if ((k = PC2[i]) == 0) 75347038Sbostic continue; 75447038Sbostic pc2inv[k-1] = i+1; 75547038Sbostic } 75647038Sbostic for (i = 0; i < 64; i++) { 75747038Sbostic if ((k = PC2[i]) == 0) 75847038Sbostic continue; 75947038Sbostic k += j; 76047038Sbostic if ((k%28) <= j) k -= 28; 76147038Sbostic perm[i] = pc2inv[k]; 76247038Sbostic } 76347038Sbostic #ifdef DEBUG 76447038Sbostic prtab("pc2tab", perm, 8); 76547038Sbostic #endif 76648484Sbostic init_perm(PC2ROT[j], perm, 8, 8); 7671958Swnj } 76847038Sbostic 7691958Swnj /* 77047038Sbostic * Bit reverse, then initial permutation, then expansion. 7711958Swnj */ 77247038Sbostic for (i = 0; i < 8; i++) { 77347038Sbostic for (j = 0; j < 8; j++) { 77447038Sbostic k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 77547038Sbostic if (k > 32) 77647038Sbostic k -= 32; 77747038Sbostic else if (k > 0) 77847038Sbostic k--; 77947038Sbostic if (k > 0) { 78047038Sbostic k--; 78147038Sbostic k = (k|07) - (k&07); 78247038Sbostic k++; 78347038Sbostic } 78447038Sbostic perm[i*8+j] = k; 78547038Sbostic } 78647038Sbostic } 78747038Sbostic #ifdef DEBUG 78847038Sbostic prtab("ietab", perm, 8); 78947038Sbostic #endif 79048484Sbostic init_perm(IE3264, perm, 4, 8); 79147038Sbostic 79247038Sbostic /* 79347038Sbostic * Compression, then final permutation, then bit reverse. 79447038Sbostic */ 79547038Sbostic for (i = 0; i < 64; i++) { 79647038Sbostic k = IP[CIFP[i]-1]; 79747038Sbostic if (k > 0) { 79847038Sbostic k--; 79947038Sbostic k = (k|07) - (k&07); 80047038Sbostic k++; 80147038Sbostic } 80247038Sbostic perm[k-1] = i+1; 80347038Sbostic } 80447038Sbostic #ifdef DEBUG 80547038Sbostic prtab("cftab", perm, 8); 80647038Sbostic #endif 80748484Sbostic init_perm(CF6464, perm, 8, 8); 80847038Sbostic 80947038Sbostic /* 81047038Sbostic * SPE table 81147038Sbostic */ 81247038Sbostic for (i = 0; i < 48; i++) 81347038Sbostic perm[i] = P32Tr[ExpandTr[i]-1]; 81447038Sbostic for (tableno = 0; tableno < 8; tableno++) { 81547038Sbostic for (j = 0; j < 64; j++) { 81647038Sbostic k = (((j >> 0) &01) << 5)| 81747038Sbostic (((j >> 1) &01) << 3)| 81847038Sbostic (((j >> 2) &01) << 2)| 81947038Sbostic (((j >> 3) &01) << 1)| 82047038Sbostic (((j >> 4) &01) << 0)| 82147038Sbostic (((j >> 5) &01) << 4); 82247038Sbostic k = S[tableno][k]; 82347038Sbostic k = (((k >> 3)&01) << 0)| 82447038Sbostic (((k >> 2)&01) << 1)| 82547038Sbostic (((k >> 1)&01) << 2)| 82647038Sbostic (((k >> 0)&01) << 3); 82747038Sbostic for (i = 0; i < 32; i++) 82847038Sbostic tmp32[i] = 0; 82947038Sbostic for (i = 0; i < 4; i++) 83047038Sbostic tmp32[4 * tableno + i] = (k >> i) & 01; 83147038Sbostic k = 0; 83247038Sbostic for (i = 24; --i >= 0; ) 83347038Sbostic k = (k<<1) | tmp32[perm[i]-1]; 83447038Sbostic TO_SIX_BIT(SPE[0][tableno][j], k); 83547038Sbostic k = 0; 83647038Sbostic for (i = 24; --i >= 0; ) 83747038Sbostic k = (k<<1) | tmp32[perm[i+24]-1]; 83847038Sbostic TO_SIX_BIT(SPE[1][tableno][j], k); 83947038Sbostic } 84047038Sbostic } 8411958Swnj } 8421958Swnj 84347038Sbostic /* 84448484Sbostic * Initialize "perm" to represent transformation "p", which rearranges 84548484Sbostic * (perhaps with expansion and/or contraction) one packed array of bits 84648484Sbostic * (of size "chars_in" characters) into another array (of size "chars_out" 84748484Sbostic * characters). 84848484Sbostic * 84947038Sbostic * "perm" must be all-zeroes on entry to this routine. 85047038Sbostic */ 85147038Sbostic STATIC 85248484Sbostic init_perm(perm, p, chars_in, chars_out) 85347038Sbostic C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; 85447038Sbostic unsigned char p[64]; 85547038Sbostic int chars_in, chars_out; 8561958Swnj { 85747038Sbostic register int i, j, k, l; 85817337Sralph 85947038Sbostic for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 86047038Sbostic l = p[k] - 1; /* where this bit comes from */ 86147038Sbostic if (l < 0) 86247038Sbostic continue; /* output bit is always 0 */ 86347038Sbostic i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 86447038Sbostic l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 86547038Sbostic for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 86647038Sbostic if ((j & l) != 0) 86747038Sbostic perm[i][j].b[k>>3] |= 1<<(k&07); 86847038Sbostic } 8691958Swnj } 87047038Sbostic } 8711958Swnj 87247038Sbostic /* 87347038Sbostic * "setkey" routine (for backwards compatibility) 87447038Sbostic */ 87547038Sbostic setkey(key) 87647038Sbostic register const char *key; 87747038Sbostic { 87847038Sbostic register int i, j, k; 87947038Sbostic C_block keyblock; 88047038Sbostic 88147038Sbostic for (i = 0; i < 8; i++) { 88247038Sbostic k = 0; 88347038Sbostic for (j = 0; j < 8; j++) { 88447038Sbostic k <<= 1; 88547038Sbostic k |= (unsigned char)*key++; 8861958Swnj } 88747038Sbostic keyblock.b[i] = k; 8881958Swnj } 889*50127Skarels return (des_setkey((char *)keyblock.b)); 8901958Swnj } 89147038Sbostic 89247038Sbostic /* 89347038Sbostic * "encrypt" routine (for backwards compatibility) 89447038Sbostic */ 89547038Sbostic encrypt(block, flag) 89647038Sbostic register char *block; 89747038Sbostic int flag; 89847038Sbostic { 89947038Sbostic register int i, j, k; 90047038Sbostic C_block cblock; 90147038Sbostic 90247038Sbostic for (i = 0; i < 8; i++) { 90347038Sbostic k = 0; 90447038Sbostic for (j = 0; j < 8; j++) { 90547038Sbostic k <<= 1; 90647038Sbostic k |= (unsigned char)*block++; 90747038Sbostic } 90847038Sbostic cblock.b[i] = k; 90947038Sbostic } 91049804Sbostic if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) 911*50127Skarels return (1); 91247038Sbostic for (i = 7; i >= 0; i--) { 91347038Sbostic k = cblock.b[i]; 91447038Sbostic for (j = 7; j >= 0; j--) { 91547038Sbostic *--block = k&01; 91647038Sbostic k >>= 1; 91747038Sbostic } 91847038Sbostic } 919*50127Skarels return (0); 92047038Sbostic } 92147038Sbostic 92247038Sbostic #ifdef DEBUG 92347038Sbostic STATIC 92447038Sbostic prtab(s, t, num_rows) 92547038Sbostic char *s; 92647038Sbostic unsigned char *t; 92747038Sbostic int num_rows; 92847038Sbostic { 92947038Sbostic register int i, j; 93047038Sbostic 93148485Sbostic (void)printf("%s:\n", s); 93247038Sbostic for (i = 0; i < num_rows; i++) { 93347038Sbostic for (j = 0; j < 8; j++) { 93448485Sbostic (void)printf("%3d", t[i*8+j]); 93547038Sbostic } 93648485Sbostic (void)printf("\n"); 93747038Sbostic } 93848485Sbostic (void)printf("\n"); 93947038Sbostic } 94047038Sbostic #endif 941