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 * 847038Sbostic * Redistribution and use in source and binary forms are permitted 947038Sbostic * provided that the above copyright notice and this paragraph are 1047038Sbostic * duplicated in all such forms and that any documentation, 1147038Sbostic * advertising materials, and other materials related to such 1247038Sbostic * distribution and use acknowledge that the software was developed 1347038Sbostic * by the University of California, Berkeley. The name of the 1447038Sbostic * University may not be used to endorse or promote products derived 1547038Sbostic * from this software without specific prior written permission. 1647038Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1747038Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1847038Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1947038Sbostic */ 2047038Sbostic 2126545Sdonn #if defined(LIBC_SCCS) && !defined(lint) 22*48484Sbostic static char sccsid[] = "@(#)crypt.c 5.6 (Berkeley) 04/21/91"; 2347038Sbostic #endif /* LIBC_SCCS and not lint */ 2422083Smckusick 2546597Sdonn #include <unistd.h> 2646597Sdonn 271958Swnj /* 2847038Sbostic * UNIX password, and DES, encryption. 2947038Sbostic * By Tom Truscott, trt@rti.rti.org, 3047038Sbostic * from algorithms by Robert W. Baldwin and James Gillogly. 3147038Sbostic * 3247038Sbostic * References: 3347038Sbostic * "Mathematical Cryptology for Computer Scientists and Mathematicians," 3447038Sbostic * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 3547038Sbostic * 3647038Sbostic * "Password Security: A Case History," R. Morris and Ken Thompson, 3747038Sbostic * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 3847038Sbostic * 3947038Sbostic * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 4047038Sbostic * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 411958Swnj */ 421958Swnj 4347038Sbostic /* ===== Configuration ==================== */ 4447038Sbostic 451958Swnj /* 4647038Sbostic * define "MUST_ALIGN" if your compiler cannot load/store 4747038Sbostic * long integers at arbitrary (e.g. odd) memory locations. 4847038Sbostic * (Either that or never pass unaligned addresses to des_cipher!) 491958Swnj */ 5047038Sbostic #if !defined(vax) 5147038Sbostic #define MUST_ALIGN 5247038Sbostic #endif 531958Swnj 541958Swnj /* 5547038Sbostic * define "LONG_IS_32_BITS" only if sizeof(long)==4. 5647038Sbostic * This avoids use of bit fields (your compiler may be sloppy with them). 571958Swnj */ 5847038Sbostic #if !defined(cray) 5947038Sbostic #define LONG_IS_32_BITS 6047038Sbostic #endif 611958Swnj 621958Swnj /* 6347038Sbostic * define "B64" to be the declaration for a 64 bit integer. 6447038Sbostic * XXX this feature is currently unused, see "endian" comment below. 651958Swnj */ 6647038Sbostic #if defined(cray) 6747038Sbostic #define B64 long 6847038Sbostic #endif 6947038Sbostic #if defined(convex) 7047038Sbostic #define B64 long long 7147038Sbostic #endif 721958Swnj 731958Swnj /* 7447038Sbostic * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 7547038Sbostic * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 76*48484Sbostic * little effect on crypt(). 771958Swnj */ 7847038Sbostic #if defined(notdef) 7947038Sbostic #define LARGEDATA 8047038Sbostic #endif 811958Swnj 82*48484Sbostic /* compile with "-DSTATIC=int" when profiling */ 83*48484Sbostic #ifndef STATIC 8447038Sbostic #define STATIC static 85*48484Sbostic #endif 86*48484Sbostic STATIC init_des(), init_perm(), permute(); 8747038Sbostic #ifdef DEBUG 8847038Sbostic STATIC prtab(); 8947038Sbostic #endif 901958Swnj 9147038Sbostic /* ==================================== */ 9247038Sbostic 931958Swnj /* 9447038Sbostic * Cipher-block representation (Bob Baldwin): 9547038Sbostic * 9647038Sbostic * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 9747038Sbostic * representation is to store one bit per byte in an array of bytes. Bit N of 9847038Sbostic * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 9947038Sbostic * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 10047038Sbostic * first byte, 9..16 in the second, and so on. The DES spec apparently has 10147038Sbostic * bit 1 in the MSB of the first byte, but that is particularly noxious so we 10247038Sbostic * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 10347038Sbostic * the MSB of the first byte. Specifically, the 64-bit input data and key are 10447038Sbostic * converted to LSB format, and the output 64-bit block is converted back into 10547038Sbostic * MSB format. 10647038Sbostic * 10747038Sbostic * DES operates internally on groups of 32 bits which are expanded to 48 bits 10847038Sbostic * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 10947038Sbostic * the computation, the expansion is applied only once, the expanded 11047038Sbostic * representation is maintained during the encryption, and a compression 11147038Sbostic * permutation is applied only at the end. To speed up the S-box lookups, 11247038Sbostic * the 48 bits are maintained as eight 6 bit groups, one per byte, which 11347038Sbostic * directly feed the eight S-boxes. Within each byte, the 6 bits are the 11447038Sbostic * most significant ones. The low two bits of each byte are zero. (Thus, 11547038Sbostic * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 11647038Sbostic * first byte in the eight byte representation, bit 2 of the 48 bit value is 117*48484Sbostic * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 11847038Sbostic * used, in which the output is the 64 bit result of an S-box lookup which 11947038Sbostic * has been permuted by P and expanded by E, and is ready for use in the next 12047038Sbostic * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 12147038Sbostic * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 12247038Sbostic * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 12347038Sbostic * "salt" are also converted to this 8*(6+2) format. The SPE table size is 12447038Sbostic * 8*64*8 = 4K bytes. 12547038Sbostic * 12647038Sbostic * To speed up bit-parallel operations (such as XOR), the 8 byte 12747038Sbostic * representation is "union"ed with 32 bit values "i0" and "i1", and, on 12847038Sbostic * machines which support it, a 64 bit value "b64". This data structure, 12947038Sbostic * "C_block", has two problems. First, alignment restrictions must be 13047038Sbostic * honored. Second, the byte-order (e.g. little-endian or big-endian) of 13147038Sbostic * the architecture becomes visible. 13247038Sbostic * 13347038Sbostic * The byte-order problem is unfortunate, since on the one hand it is good 13447038Sbostic * to have a machine-independent C_block representation (bits 1..8 in the 13547038Sbostic * first byte, etc.), and on the other hand it is good for the LSB of the 13647038Sbostic * first byte to be the LSB of i0. We cannot have both these things, so we 13747038Sbostic * currently use the "little-endian" representation and avoid any multi-byte 13847038Sbostic * operations that depend on byte order. This largely precludes use of the 13947038Sbostic * 64-bit datatype since the relative order of i0 and i1 are unknown. It 14047038Sbostic * also inhibits grouping the SPE table to look up 12 bits at a time. (The 14147038Sbostic * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 142*48484Sbostic * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 14347038Sbostic * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 14447038Sbostic * requires a 128 kilobyte table, so perhaps this is not a big loss. 14547038Sbostic * 14647038Sbostic * Permutation representation (Jim Gillogly): 14747038Sbostic * 14847038Sbostic * A transformation is defined by its effect on each of the 8 bytes of the 14947038Sbostic * 64-bit input. For each byte we give a 64-bit output that has the bits in 15047038Sbostic * the input distributed appropriately. The transformation is then the OR 15147038Sbostic * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 15247038Sbostic * each transformation. Unless LARGEDATA is defined, however, a more compact 15347038Sbostic * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 15447038Sbostic * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 15547038Sbostic * is slower but tolerable, particularly for password encryption in which 15647038Sbostic * the SPE transformation is iterated many times. The small tables total 9K 15747038Sbostic * bytes, the large tables total 72K bytes. 15847038Sbostic * 15947038Sbostic * The transformations used are: 16047038Sbostic * IE3264: MSB->LSB conversion, initial permutation, and expansion. 16147038Sbostic * This is done by collecting the 32 even-numbered bits and applying 16247038Sbostic * a 32->64 bit transformation, and then collecting the 32 odd-numbered 16347038Sbostic * bits and applying the same transformation. Since there are only 16447038Sbostic * 32 input bits, the IE3264 transformation table is half the size of 16547038Sbostic * the usual table. 16647038Sbostic * CF6464: Compression, final permutation, and LSB->MSB conversion. 16747038Sbostic * This is done by two trivial 48->32 bit compressions to obtain 16847038Sbostic * a 64-bit block (the bit numbering is given in the "CIFP" table) 16947038Sbostic * followed by a 64->64 bit "cleanup" transformation. (It would 17047038Sbostic * be possible to group the bits in the 64-bit block so that 2 17147038Sbostic * identical 32->32 bit transformations could be used instead, 17247038Sbostic * saving a factor of 4 in space and possibly 2 in time, but 17347038Sbostic * byte-ordering and other complications rear their ugly head. 17447038Sbostic * Similar opportunities/problems arise in the key schedule 17547038Sbostic * transforms.) 17647038Sbostic * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 17747038Sbostic * This admittedly baroque 64->64 bit transformation is used to 17847038Sbostic * produce the first code (in 8*(6+2) format) of the key schedule. 17947038Sbostic * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 18047038Sbostic * It would be possible to define 15 more transformations, each 18147038Sbostic * with a different rotation, to generate the entire key schedule. 18247038Sbostic * To save space, however, we instead permute each code into the 18347038Sbostic * next by using a transformation that "undoes" the PC2 permutation, 18447038Sbostic * rotates the code, and then applies PC2. Unfortunately, PC2 18547038Sbostic * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 18647038Sbostic * invertible. We get around that problem by using a modified PC2 18747038Sbostic * which retains the 8 otherwise-lost bits in the unused low-order 18847038Sbostic * bits of each byte. The low-order bits are cleared when the 18947038Sbostic * codes are stored into the key schedule. 19047038Sbostic * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 19147038Sbostic * This is faster than applying PC2ROT[0] twice, 19247038Sbostic * 19347038Sbostic * The Bell Labs "salt" (Bob Baldwin): 19447038Sbostic * 19547038Sbostic * The salting is a simple permutation applied to the 48-bit result of E. 19647038Sbostic * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 19747038Sbostic * i+24 of the result are swapped. The salt is thus a 24 bit number, with 19847038Sbostic * 16777216 possible values. (The original salt was 12 bits and could not 19947038Sbostic * swap bits 13..24 with 36..48.) 20047038Sbostic * 201*48484Sbostic * It is possible, but ugly, to warp the SPE table to account for the salt 202*48484Sbostic * permutation. Fortunately, the conditional bit swapping requires only 203*48484Sbostic * about four machine instructions and can be done on-the-fly with about an 204*48484Sbostic * 8% performance penalty. 2051958Swnj */ 206*48484Sbostic 20747038Sbostic typedef union { 20847038Sbostic unsigned char b[8]; 20947038Sbostic struct { 21047038Sbostic #if defined(LONG_IS_32_BITS) 21147038Sbostic /* long is often faster than a 32-bit bit field */ 21247038Sbostic long i0; 21347038Sbostic long i1; 21447038Sbostic #else 21547038Sbostic long i0: 32; 21647038Sbostic long i1: 32; 21747038Sbostic #endif 21847038Sbostic } b32; 21947038Sbostic #if defined(B64) 22047038Sbostic B64 b64; 22147038Sbostic #endif 22247038Sbostic } C_block; 2231958Swnj 2241958Swnj /* 22547038Sbostic * Convert twenty-four-bit long in host-order 22647038Sbostic * to six bits (and 2 low-order zeroes) per char little-endian format. 2271958Swnj */ 22847038Sbostic #define TO_SIX_BIT(rslt, src) { \ 22947038Sbostic C_block cvt; \ 23047038Sbostic cvt.b[0] = src; src >>= 6; \ 23147038Sbostic cvt.b[1] = src; src >>= 6; \ 23247038Sbostic cvt.b[2] = src; src >>= 6; \ 23347038Sbostic cvt.b[3] = src; \ 23447038Sbostic rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 23547038Sbostic } 2361958Swnj 2371958Swnj /* 23847038Sbostic * These macros may someday permit efficient use of 64-bit integers. 23917337Sralph */ 24047038Sbostic #define ZERO(d,d0,d1) d0 = 0, d1 = 0 24147038Sbostic #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 24247038Sbostic #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 24347038Sbostic #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 24447038Sbostic #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 24547038Sbostic #define DCL_BLOCK(d,d0,d1) long d0, d1 24647038Sbostic 24747038Sbostic #if defined(LARGEDATA) 24847038Sbostic /* Waste memory like crazy. Also, do permutations in line */ 24947038Sbostic #define LGCHUNKBITS 3 25047038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 25147038Sbostic #define PERM6464(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 OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 25747038Sbostic OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 25847038Sbostic OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 25947038Sbostic OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 26047038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 26147038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 26247038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 26347038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 26447038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 26547038Sbostic #else 26647038Sbostic /* "small data" */ 26747038Sbostic #define LGCHUNKBITS 2 26847038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 26947038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 27047038Sbostic { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 27147038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 27247038Sbostic { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 27347038Sbostic 27447038Sbostic STATIC 27547038Sbostic permute(cp, out, p, chars_in) 27647038Sbostic unsigned char *cp; 27747038Sbostic C_block *out; 27847038Sbostic register C_block *p; 27947038Sbostic int chars_in; 28047038Sbostic { 28147038Sbostic register DCL_BLOCK(D,D0,D1); 28247038Sbostic register C_block *tp; 28347038Sbostic register int t; 28447038Sbostic 28547038Sbostic ZERO(D,D0,D1); 28647038Sbostic do { 28747038Sbostic t = *cp++; 28847038Sbostic tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 28947038Sbostic tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 29047038Sbostic } while (--chars_in > 0); 29147038Sbostic STORE(D,D0,D1,*out); 29247038Sbostic } 29347038Sbostic #endif /* LARGEDATA */ 29447038Sbostic 29547038Sbostic 29647038Sbostic /* ===== (mostly) Standard DES Tables ==================== */ 29747038Sbostic 29847038Sbostic static unsigned char IP[] = { /* initial permutation */ 29947038Sbostic 58, 50, 42, 34, 26, 18, 10, 2, 30047038Sbostic 60, 52, 44, 36, 28, 20, 12, 4, 30147038Sbostic 62, 54, 46, 38, 30, 22, 14, 6, 30247038Sbostic 64, 56, 48, 40, 32, 24, 16, 8, 30347038Sbostic 57, 49, 41, 33, 25, 17, 9, 1, 30447038Sbostic 59, 51, 43, 35, 27, 19, 11, 3, 30547038Sbostic 61, 53, 45, 37, 29, 21, 13, 5, 30647038Sbostic 63, 55, 47, 39, 31, 23, 15, 7, 30717337Sralph }; 30817337Sralph 30947038Sbostic /* The final permutation is the inverse of IP - no table is necessary */ 31047038Sbostic 31147038Sbostic static unsigned char ExpandTr[] = { /* expansion operation */ 31247038Sbostic 32, 1, 2, 3, 4, 5, 31347038Sbostic 4, 5, 6, 7, 8, 9, 31447038Sbostic 8, 9, 10, 11, 12, 13, 31547038Sbostic 12, 13, 14, 15, 16, 17, 31647038Sbostic 16, 17, 18, 19, 20, 21, 31747038Sbostic 20, 21, 22, 23, 24, 25, 31847038Sbostic 24, 25, 26, 27, 28, 29, 31947038Sbostic 28, 29, 30, 31, 32, 1, 32047038Sbostic }; 32147038Sbostic 32247038Sbostic static unsigned char PC1[] = { /* permuted choice table (key) */ 32347038Sbostic 57, 49, 41, 33, 25, 17, 9, 32447038Sbostic 1, 58, 50, 42, 34, 26, 18, 32547038Sbostic 10, 2, 59, 51, 43, 35, 27, 32647038Sbostic 19, 11, 3, 60, 52, 44, 36, 32747038Sbostic 32847038Sbostic 63, 55, 47, 39, 31, 23, 15, 32947038Sbostic 7, 62, 54, 46, 38, 30, 22, 33047038Sbostic 14, 6, 61, 53, 45, 37, 29, 33147038Sbostic 21, 13, 5, 28, 20, 12, 4, 33247038Sbostic }; 33347038Sbostic 33447038Sbostic static unsigned char Rotates[] = { /* number of rotations of PC1 */ 33547038Sbostic 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 33647038Sbostic }; 33747038Sbostic 33847038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 33947038Sbostic static unsigned char PC2[] = { /* permuted choice key (table) */ 34047038Sbostic 9, 18, 14, 17, 11, 24, 1, 5, 34147038Sbostic 22, 25, 3, 28, 15, 6, 21, 10, 34247038Sbostic 35, 38, 23, 19, 12, 4, 26, 8, 34347038Sbostic 43, 54, 16, 7, 27, 20, 13, 2, 34447038Sbostic 34547038Sbostic 0, 0, 41, 52, 31, 37, 47, 55, 34647038Sbostic 0, 0, 30, 40, 51, 45, 33, 48, 34747038Sbostic 0, 0, 44, 49, 39, 56, 34, 53, 34847038Sbostic 0, 0, 46, 42, 50, 36, 29, 32, 34947038Sbostic }; 35047038Sbostic 35147038Sbostic static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 35247038Sbostic /* S[1] */ 35347038Sbostic 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 35447038Sbostic 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 35547038Sbostic 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 35647038Sbostic 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 35747038Sbostic /* S[2] */ 35847038Sbostic 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 35947038Sbostic 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 36047038Sbostic 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 36147038Sbostic 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 36247038Sbostic /* S[3] */ 36347038Sbostic 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 36447038Sbostic 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 36547038Sbostic 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 36647038Sbostic 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 36747038Sbostic /* S[4] */ 36847038Sbostic 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 36947038Sbostic 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 37047038Sbostic 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 37147038Sbostic 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 37247038Sbostic /* S[5] */ 37347038Sbostic 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 37447038Sbostic 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 37547038Sbostic 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 37647038Sbostic 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 37747038Sbostic /* S[6] */ 37847038Sbostic 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 37947038Sbostic 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 38047038Sbostic 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 38147038Sbostic 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 38247038Sbostic /* S[7] */ 38347038Sbostic 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 38447038Sbostic 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 38547038Sbostic 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 38647038Sbostic 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 38747038Sbostic /* S[8] */ 38847038Sbostic 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 38947038Sbostic 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 39047038Sbostic 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 39147038Sbostic 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 39247038Sbostic }; 39347038Sbostic 39447038Sbostic static unsigned char P32Tr[] = { /* 32-bit permutation function */ 39547038Sbostic 16, 7, 20, 21, 39647038Sbostic 29, 12, 28, 17, 39747038Sbostic 1, 15, 23, 26, 39847038Sbostic 5, 18, 31, 10, 39947038Sbostic 2, 8, 24, 14, 40047038Sbostic 32, 27, 3, 9, 40147038Sbostic 19, 13, 30, 6, 40247038Sbostic 22, 11, 4, 25, 40347038Sbostic }; 40447038Sbostic 40547038Sbostic static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 40647038Sbostic 1, 2, 3, 4, 17, 18, 19, 20, 40747038Sbostic 5, 6, 7, 8, 21, 22, 23, 24, 40847038Sbostic 9, 10, 11, 12, 25, 26, 27, 28, 40947038Sbostic 13, 14, 15, 16, 29, 30, 31, 32, 41047038Sbostic 41147038Sbostic 33, 34, 35, 36, 49, 50, 51, 52, 41247038Sbostic 37, 38, 39, 40, 53, 54, 55, 56, 41347038Sbostic 41, 42, 43, 44, 57, 58, 59, 60, 41447038Sbostic 45, 46, 47, 48, 61, 62, 63, 64, 41547038Sbostic }; 41647038Sbostic 41747038Sbostic static unsigned char itoa64[] = /* 0..63 => ascii-64 */ 41847038Sbostic "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 41947038Sbostic 42047038Sbostic 42147038Sbostic /* ===== Tables that are initialized at run time ==================== */ 42247038Sbostic 42347038Sbostic 42447038Sbostic static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ 42547038Sbostic 42647038Sbostic /* Initial key schedule permutation */ 42747038Sbostic static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 42847038Sbostic 42947038Sbostic /* Subsequent key schedule rotation permutations */ 43047038Sbostic static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 43147038Sbostic 43247038Sbostic /* Initial permutation/expansion table */ 43347038Sbostic static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 43447038Sbostic 43547038Sbostic /* Table that combines the S, P, and E operations. */ 43647038Sbostic static long SPE[2][8][64]; 43747038Sbostic 43847038Sbostic /* compressed/interleaved => final permutation table */ 43947038Sbostic static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 44047038Sbostic 44147038Sbostic 44247038Sbostic /* ==================================== */ 44347038Sbostic 44447038Sbostic 44547038Sbostic static C_block constdatablock; /* encryption constant */ 44647038Sbostic static char cryptresult[1+4+4+11+1]; /* encrypted result */ 44747038Sbostic 44817337Sralph /* 449*48484Sbostic * Return a pointer to static data consisting of the "setting" 450*48484Sbostic * followed by an encryption produced by the "key" and "setting". 4511958Swnj */ 45247038Sbostic char * 45347038Sbostic crypt(key, setting) 45447038Sbostic register const char *key; 45547038Sbostic register const char *setting; 4561958Swnj { 45747038Sbostic register char *encp; 45847038Sbostic register long i; 459*48484Sbostic register int t; 46047038Sbostic long salt; 46147038Sbostic int num_iter, salt_size, key_size; 46247038Sbostic C_block keyblock, rsltblock; 4631958Swnj 464*48484Sbostic for (i = 0; i < 8; i++) { 465*48484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 46647038Sbostic key++; 467*48484Sbostic keyblock.b[i] = t; 468*48484Sbostic } 46947038Sbostic des_setkey((char *)keyblock.b); /* also initializes "a64toi" */ 47047038Sbostic 47147038Sbostic encp = &cryptresult[0]; 47247038Sbostic if (*setting != '_') { /* old style */ 47347038Sbostic num_iter = 25; 47447038Sbostic salt_size = 2; 47547038Sbostic key_size = 8; 47647038Sbostic } 47747038Sbostic else { /* new style */ 47847038Sbostic *encp++ = *setting++; 47947038Sbostic 48047038Sbostic /* get iteration count */ 48147038Sbostic num_iter = 0; 48247038Sbostic for (i = 4; --i >= 0; ) { 483*48484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 484*48484Sbostic t = '.'; 485*48484Sbostic encp[i] = t; 486*48484Sbostic num_iter = (num_iter<<6) | a64toi[t]; 48747038Sbostic } 48847038Sbostic setting += 4; 48947038Sbostic encp += 4; 49047038Sbostic salt_size = 4; 49147038Sbostic key_size = 128; 49247038Sbostic } 49347038Sbostic 49447038Sbostic salt = 0; 49547038Sbostic for (i = salt_size; --i >= 0; ) { 496*48484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 497*48484Sbostic t = '.'; 498*48484Sbostic encp[i] = t; 499*48484Sbostic salt = (salt<<6) | a64toi[t]; 50047038Sbostic } 50147038Sbostic encp += salt_size; 50247038Sbostic des_cipher((char *)&constdatablock, (char *)&rsltblock, salt, num_iter); 50347038Sbostic 5041958Swnj /* 50547038Sbostic * encrypt the remainder of the password 8 characters at a time. 5061958Swnj */ 50747038Sbostic while ((key_size -= 8) > 0 && *key) { 50847038Sbostic C_block xdatablock; 50947038Sbostic 510*48484Sbostic for (i = 0; i < 8; i++) { 511*48484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 51247038Sbostic key++; 513*48484Sbostic keyblock.b[i] = t; 514*48484Sbostic if (t == 0) 51547038Sbostic break; /* pad out with previous key */ 516*48484Sbostic } 51747038Sbostic des_setkey((char *)keyblock.b); 51847038Sbostic des_cipher((char *)&constdatablock, (char *)&xdatablock, 0L, 1); 51947038Sbostic rsltblock.b32.i0 ^= xdatablock.b32.i0; 52047038Sbostic rsltblock.b32.i1 ^= xdatablock.b32.i1; 5211958Swnj } 52247038Sbostic 5231958Swnj /* 52447038Sbostic * Encode the 64 cipher bits as 11 ascii characters. 5251958Swnj */ 52647038Sbostic i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; 52747038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 52847038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 52947038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53047038Sbostic encp[0] = itoa64[i]; encp += 4; 53147038Sbostic i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; 53247038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 53347038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53447038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53547038Sbostic encp[0] = itoa64[i]; encp += 4; 53647038Sbostic i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 53747038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53847038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53947038Sbostic encp[0] = itoa64[i]; 54047038Sbostic 54147038Sbostic encp[3] = 0; 542*48484Sbostic 54347038Sbostic return(cryptresult); 54447038Sbostic } 54547038Sbostic 54647038Sbostic 54747038Sbostic /* 54847038Sbostic * The Key Schedule, filled in by des_setkey() or setkey(). 54947038Sbostic */ 55047038Sbostic #define KS_SIZE 16 55147038Sbostic static C_block KS[KS_SIZE]; 55247038Sbostic 55347038Sbostic /* 55447038Sbostic * Set up the key schedule from the key. 55547038Sbostic */ 55647038Sbostic void 55747038Sbostic des_setkey(key) 55847038Sbostic register const char *key; 55947038Sbostic { 56047038Sbostic register DCL_BLOCK(K, K0, K1); 56147038Sbostic register C_block *ptabp; 56247038Sbostic register int i; 56347038Sbostic static int des_ready = 0; 56447038Sbostic 56547038Sbostic if (!des_ready) { 56647038Sbostic init_des(); 56747038Sbostic des_ready = 1; 5681958Swnj } 56917337Sralph 57047038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); 57147038Sbostic key = (char *)&KS[0]; 57247038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 57347038Sbostic for (i = 1; i < 16; i++) { 57447038Sbostic key += sizeof(C_block); 57547038Sbostic STORE(K,K0,K1,*(C_block *)key); 57647038Sbostic ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 57747038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,ptabp); 57847038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 57947038Sbostic } 5801958Swnj } 5811958Swnj 5821958Swnj /* 58347038Sbostic * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 58447038Sbostic * iterations of DES, using the the given 24-bit salt and the pre-computed key 58547038Sbostic * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 58647038Sbostic * 58747038Sbostic * NOTE: the performance of this routine is critically dependent on your 58847038Sbostic * compiler and machine architecture. 5891958Swnj */ 59047038Sbostic void 59147038Sbostic des_cipher(in, out, salt, num_iter) 59247038Sbostic const char *in; 59347038Sbostic char *out; 594*48484Sbostic long salt; 59547038Sbostic int num_iter; 59647038Sbostic { 59747038Sbostic /* variables that we want in registers, most important first */ 59847038Sbostic #if defined(pdp11) 59947038Sbostic register int j; 60047038Sbostic #endif 60147038Sbostic register long L0, L1, R0, R1, k; 60247038Sbostic register C_block *kp; 60347038Sbostic register int ks_inc, loop_count; 60447038Sbostic C_block B; 6051958Swnj 60647038Sbostic L0 = salt; 60747038Sbostic TO_SIX_BIT(salt, L0); /* convert to 8*(6+2) format */ 6081958Swnj 60947038Sbostic #if defined(vax) || defined(pdp11) 61047038Sbostic salt = ~salt; /* "x &~ y" is faster than "x & y". */ 61147038Sbostic #define SALT (~salt) 61247038Sbostic #else 61347038Sbostic #define SALT salt 61447038Sbostic #endif 6151958Swnj 61647038Sbostic #if defined(MUST_ALIGN) 61747038Sbostic B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 61847038Sbostic B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 61947038Sbostic LOAD(L,L0,L1,B); 62047038Sbostic #else 62147038Sbostic LOAD(L,L0,L1,*(C_block *)in); 62247038Sbostic #endif 62347038Sbostic LOADREG(R,R0,R1,L,L0,L1); 62447038Sbostic L0 &= 0x55555555L; 62547038Sbostic L1 &= 0x55555555L; 62647038Sbostic L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ 62747038Sbostic R0 &= 0xaaaaaaaaL; 62847038Sbostic R1 = (R1 >> 1) & 0x55555555L; 62947038Sbostic L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 63047038Sbostic STORE(L,L0,L1,B); 63147038Sbostic PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 63247038Sbostic PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 6331958Swnj 63447038Sbostic if (num_iter >= 0) 63547038Sbostic { /* encryption */ 63647038Sbostic kp = &KS[0]; 63747038Sbostic ks_inc = sizeof(*kp); 63847038Sbostic } 63947038Sbostic else 64047038Sbostic { /* decryption */ 64147038Sbostic num_iter = -num_iter; 64247038Sbostic kp = &KS[KS_SIZE-1]; 64347038Sbostic ks_inc = -sizeof(*kp); 64447038Sbostic } 6451958Swnj 64647038Sbostic while (--num_iter >= 0) { 64747038Sbostic loop_count = 8; 64847038Sbostic do { 6491958Swnj 65047038Sbostic #define BTAB(i) (((unsigned char *)&B.b[0])[i]) 65147038Sbostic #define SPTAB(t, i) (*(long *)((unsigned char *)t \ 65247038Sbostic + i*(sizeof(long)/4))) 65347038Sbostic #if defined(gould) 65447038Sbostic /* use this if BTAB(i) is evaluated just once ... */ 65547038Sbostic #define DOXOR(a,b,i) a^=SPTAB(SPE[0][i],BTAB(i));b^=SPTAB(SPE[1][i],BTAB(i)); 65647038Sbostic #else 65747038Sbostic #if defined(pdp11) 65847038Sbostic /* use this if your "long" int indexing is slow */ 65947038Sbostic #define DOXOR(a,b,i) j=BTAB(i); a^=SPTAB(SPE[0][i],j); b^=SPTAB(SPE[1][i],j); 66047038Sbostic #else 66147038Sbostic /* use this if "k" is allocated to a register ... */ 66247038Sbostic #define DOXOR(a,b,i) k=BTAB(i); a^=SPTAB(SPE[0][i],k); b^=SPTAB(SPE[1][i],k); 66347038Sbostic #endif 66447038Sbostic #endif 6651958Swnj 66647038Sbostic #define CRUNCH(L0, L1, R0, R1) \ 66747038Sbostic k = (R0 ^ R1) & SALT; \ 66847038Sbostic B.b32.i0 = k ^ R0 ^ kp->b32.i0; \ 66947038Sbostic B.b32.i1 = k ^ R1 ^ kp->b32.i1; \ 67047038Sbostic kp = (C_block *)((char *)kp+ks_inc); \ 67147038Sbostic \ 67247038Sbostic DOXOR(L0, L1, 0); \ 67347038Sbostic DOXOR(L0, L1, 1); \ 67447038Sbostic DOXOR(L0, L1, 2); \ 67547038Sbostic DOXOR(L0, L1, 3); \ 67647038Sbostic DOXOR(L0, L1, 4); \ 67747038Sbostic DOXOR(L0, L1, 5); \ 67847038Sbostic DOXOR(L0, L1, 6); \ 67947038Sbostic DOXOR(L0, L1, 7); 6801958Swnj 68147038Sbostic CRUNCH(L0, L1, R0, R1); 68247038Sbostic CRUNCH(R0, R1, L0, L1); 68347038Sbostic } while (--loop_count != 0); 68447038Sbostic kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 6851958Swnj 6861958Swnj 68747038Sbostic /* swap L and R */ 68847038Sbostic L0 ^= R0; L1 ^= R1; 68947038Sbostic R0 ^= L0; R1 ^= L1; 69047038Sbostic L0 ^= R0; L1 ^= R1; 69147038Sbostic } 6921958Swnj 69347038Sbostic /* store the encrypted (or decrypted) result */ 69447038Sbostic L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); 69547038Sbostic L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); 69647038Sbostic STORE(L,L0,L1,B); 69747038Sbostic PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 69847038Sbostic #if defined(MUST_ALIGN) 69947038Sbostic STORE(L,L0,L1,B); 70047038Sbostic out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 70147038Sbostic out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 70247038Sbostic #else 70347038Sbostic STORE(L,L0,L1,*(C_block *)out); 70447038Sbostic #endif 70547038Sbostic } 70647038Sbostic 70747038Sbostic 7081958Swnj /* 70947038Sbostic * Initialize various tables. This need only be done once. It could even be 71047038Sbostic * done at compile time, if the compiler were capable of that sort of thing. 7111958Swnj */ 71247038Sbostic STATIC 71347038Sbostic init_des() 7141958Swnj { 71547038Sbostic register int i, j; 71647038Sbostic register long k; 71747038Sbostic register int tableno; 71847038Sbostic static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 7191958Swnj 7201958Swnj /* 72147038Sbostic * table that converts chars "./0-9A-Za-z"to integers 0-63. 7221958Swnj */ 72347038Sbostic for (i = 0; i < 64; i++) 72447038Sbostic a64toi[itoa64[i]] = i; 72547038Sbostic 7261958Swnj /* 72747038Sbostic * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 7281958Swnj */ 72947038Sbostic for (i = 0; i < 64; i++) 73047038Sbostic perm[i] = 0; 73147038Sbostic for (i = 0; i < 64; i++) { 73247038Sbostic if ((k = PC2[i]) == 0) 73347038Sbostic continue; 73447038Sbostic k += Rotates[0]-1; 73547038Sbostic if ((k%28) < Rotates[0]) k -= 28; 73647038Sbostic k = PC1[k]; 73747038Sbostic if (k > 0) { 73847038Sbostic k--; 73947038Sbostic k = (k|07) - (k&07); 74047038Sbostic k++; 7411958Swnj } 74247038Sbostic perm[i] = k; 7431958Swnj } 74447038Sbostic #ifdef DEBUG 74547038Sbostic prtab("pc1tab", perm, 8); 74647038Sbostic #endif 747*48484Sbostic init_perm(PC1ROT, perm, 8, 8); 74847038Sbostic 7491958Swnj /* 75047038Sbostic * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 7511958Swnj */ 75247038Sbostic for (j = 0; j < 2; j++) { 75347038Sbostic unsigned char pc2inv[64]; 75447038Sbostic for (i = 0; i < 64; i++) 75547038Sbostic perm[i] = pc2inv[i] = 0; 75647038Sbostic for (i = 0; i < 64; i++) { 75747038Sbostic if ((k = PC2[i]) == 0) 75847038Sbostic continue; 75947038Sbostic pc2inv[k-1] = i+1; 76047038Sbostic } 76147038Sbostic for (i = 0; i < 64; i++) { 76247038Sbostic if ((k = PC2[i]) == 0) 76347038Sbostic continue; 76447038Sbostic k += j; 76547038Sbostic if ((k%28) <= j) k -= 28; 76647038Sbostic perm[i] = pc2inv[k]; 76747038Sbostic } 76847038Sbostic #ifdef DEBUG 76947038Sbostic prtab("pc2tab", perm, 8); 77047038Sbostic #endif 771*48484Sbostic init_perm(PC2ROT[j], perm, 8, 8); 7721958Swnj } 77347038Sbostic 7741958Swnj /* 77547038Sbostic * Bit reverse, then initial permutation, then expansion. 7761958Swnj */ 77747038Sbostic for (i = 0; i < 8; i++) { 77847038Sbostic for (j = 0; j < 8; j++) { 77947038Sbostic k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 78047038Sbostic if (k > 32) 78147038Sbostic k -= 32; 78247038Sbostic else if (k > 0) 78347038Sbostic k--; 78447038Sbostic if (k > 0) { 78547038Sbostic k--; 78647038Sbostic k = (k|07) - (k&07); 78747038Sbostic k++; 78847038Sbostic } 78947038Sbostic perm[i*8+j] = k; 79047038Sbostic } 79147038Sbostic } 79247038Sbostic #ifdef DEBUG 79347038Sbostic prtab("ietab", perm, 8); 79447038Sbostic #endif 795*48484Sbostic init_perm(IE3264, perm, 4, 8); 79647038Sbostic 79747038Sbostic /* 79847038Sbostic * Compression, then final permutation, then bit reverse. 79947038Sbostic */ 80047038Sbostic for (i = 0; i < 64; i++) { 80147038Sbostic k = IP[CIFP[i]-1]; 80247038Sbostic if (k > 0) { 80347038Sbostic k--; 80447038Sbostic k = (k|07) - (k&07); 80547038Sbostic k++; 80647038Sbostic } 80747038Sbostic perm[k-1] = i+1; 80847038Sbostic } 80947038Sbostic #ifdef DEBUG 81047038Sbostic prtab("cftab", perm, 8); 81147038Sbostic #endif 812*48484Sbostic init_perm(CF6464, perm, 8, 8); 81347038Sbostic 81447038Sbostic /* 81547038Sbostic * SPE table 81647038Sbostic */ 81747038Sbostic for (i = 0; i < 48; i++) 81847038Sbostic perm[i] = P32Tr[ExpandTr[i]-1]; 81947038Sbostic for (tableno = 0; tableno < 8; tableno++) { 82047038Sbostic for (j = 0; j < 64; j++) { 82147038Sbostic k = (((j >> 0) &01) << 5)| 82247038Sbostic (((j >> 1) &01) << 3)| 82347038Sbostic (((j >> 2) &01) << 2)| 82447038Sbostic (((j >> 3) &01) << 1)| 82547038Sbostic (((j >> 4) &01) << 0)| 82647038Sbostic (((j >> 5) &01) << 4); 82747038Sbostic k = S[tableno][k]; 82847038Sbostic k = (((k >> 3)&01) << 0)| 82947038Sbostic (((k >> 2)&01) << 1)| 83047038Sbostic (((k >> 1)&01) << 2)| 83147038Sbostic (((k >> 0)&01) << 3); 83247038Sbostic for (i = 0; i < 32; i++) 83347038Sbostic tmp32[i] = 0; 83447038Sbostic for (i = 0; i < 4; i++) 83547038Sbostic tmp32[4 * tableno + i] = (k >> i) & 01; 83647038Sbostic k = 0; 83747038Sbostic for (i = 24; --i >= 0; ) 83847038Sbostic k = (k<<1) | tmp32[perm[i]-1]; 83947038Sbostic TO_SIX_BIT(SPE[0][tableno][j], k); 84047038Sbostic k = 0; 84147038Sbostic for (i = 24; --i >= 0; ) 84247038Sbostic k = (k<<1) | tmp32[perm[i+24]-1]; 84347038Sbostic TO_SIX_BIT(SPE[1][tableno][j], k); 84447038Sbostic } 84547038Sbostic } 8461958Swnj } 8471958Swnj 84847038Sbostic /* 849*48484Sbostic * Initialize "perm" to represent transformation "p", which rearranges 850*48484Sbostic * (perhaps with expansion and/or contraction) one packed array of bits 851*48484Sbostic * (of size "chars_in" characters) into another array (of size "chars_out" 852*48484Sbostic * characters). 853*48484Sbostic * 85447038Sbostic * "perm" must be all-zeroes on entry to this routine. 85547038Sbostic */ 85647038Sbostic STATIC 857*48484Sbostic init_perm(perm, p, chars_in, chars_out) 85847038Sbostic C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; 85947038Sbostic unsigned char p[64]; 86047038Sbostic int chars_in, chars_out; 8611958Swnj { 86247038Sbostic register int i, j, k, l; 86317337Sralph 86447038Sbostic for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 86547038Sbostic l = p[k] - 1; /* where this bit comes from */ 86647038Sbostic if (l < 0) 86747038Sbostic continue; /* output bit is always 0 */ 86847038Sbostic i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 86947038Sbostic l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 87047038Sbostic for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 87147038Sbostic if ((j & l) != 0) 87247038Sbostic perm[i][j].b[k>>3] |= 1<<(k&07); 87347038Sbostic } 8741958Swnj } 87547038Sbostic } 8761958Swnj 87747038Sbostic /* 87847038Sbostic * "setkey" routine (for backwards compatibility) 87947038Sbostic */ 88047038Sbostic void 88147038Sbostic setkey(key) 88247038Sbostic register const char *key; 88347038Sbostic { 88447038Sbostic register int i, j, k; 88547038Sbostic C_block keyblock; 88647038Sbostic 88747038Sbostic for (i = 0; i < 8; i++) { 88847038Sbostic k = 0; 88947038Sbostic for (j = 0; j < 8; j++) { 89047038Sbostic k <<= 1; 89147038Sbostic k |= (unsigned char)*key++; 8921958Swnj } 89347038Sbostic keyblock.b[i] = k; 8941958Swnj } 89547038Sbostic des_setkey((char *)keyblock.b); 8961958Swnj } 89747038Sbostic 89847038Sbostic /* 89947038Sbostic * "encrypt" routine (for backwards compatibility) 90047038Sbostic */ 90147038Sbostic void 90247038Sbostic encrypt(block, flag) 90347038Sbostic register char *block; 90447038Sbostic int flag; 90547038Sbostic { 90647038Sbostic register int i, j, k; 90747038Sbostic C_block cblock; 90847038Sbostic 90947038Sbostic for (i = 0; i < 8; i++) { 91047038Sbostic k = 0; 91147038Sbostic for (j = 0; j < 8; j++) { 91247038Sbostic k <<= 1; 91347038Sbostic k |= (unsigned char)*block++; 91447038Sbostic } 91547038Sbostic cblock.b[i] = k; 91647038Sbostic } 91747038Sbostic des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag? -1: 1)); 91847038Sbostic for (i = 7; i >= 0; i--) { 91947038Sbostic k = cblock.b[i]; 92047038Sbostic for (j = 7; j >= 0; j--) { 92147038Sbostic *--block = k&01; 92247038Sbostic k >>= 1; 92347038Sbostic } 92447038Sbostic } 92547038Sbostic } 92647038Sbostic 92747038Sbostic #ifdef DEBUG 92847038Sbostic STATIC 92947038Sbostic prtab(s, t, num_rows) 93047038Sbostic char *s; 93147038Sbostic unsigned char *t; 93247038Sbostic int num_rows; 93347038Sbostic { 93447038Sbostic register int i, j; 93547038Sbostic 93647038Sbostic printf("%s:\n", s); 93747038Sbostic for (i = 0; i < num_rows; i++) { 93847038Sbostic for (j = 0; j < 8; j++) { 93947038Sbostic printf("%3d", t[i*8+j]); 94047038Sbostic } 94147038Sbostic printf("\n"); 94247038Sbostic } 94347038Sbostic printf("\n"); 94447038Sbostic } 94547038Sbostic #endif 946