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*48485Sbostic static char sccsid[] = "@(#)crypt.c 5.7 (Berkeley) 04/21/91"; 2347038Sbostic #endif /* LIBC_SCCS and not lint */ 2422083Smckusick 2546597Sdonn #include <unistd.h> 26*48485Sbostic #include <pwd.h> 2746597Sdonn 281958Swnj /* 2947038Sbostic * UNIX password, and DES, encryption. 3047038Sbostic * By Tom Truscott, trt@rti.rti.org, 3147038Sbostic * from algorithms by Robert W. Baldwin and James Gillogly. 3247038Sbostic * 3347038Sbostic * References: 3447038Sbostic * "Mathematical Cryptology for Computer Scientists and Mathematicians," 3547038Sbostic * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 3647038Sbostic * 3747038Sbostic * "Password Security: A Case History," R. Morris and Ken Thompson, 3847038Sbostic * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 3947038Sbostic * 4047038Sbostic * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 4147038Sbostic * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 421958Swnj */ 431958Swnj 4447038Sbostic /* ===== Configuration ==================== */ 4547038Sbostic 461958Swnj /* 4747038Sbostic * define "MUST_ALIGN" if your compiler cannot load/store 4847038Sbostic * long integers at arbitrary (e.g. odd) memory locations. 4947038Sbostic * (Either that or never pass unaligned addresses to des_cipher!) 501958Swnj */ 5147038Sbostic #if !defined(vax) 5247038Sbostic #define MUST_ALIGN 5347038Sbostic #endif 541958Swnj 551958Swnj /* 5647038Sbostic * define "LONG_IS_32_BITS" only if sizeof(long)==4. 5747038Sbostic * This avoids use of bit fields (your compiler may be sloppy with them). 581958Swnj */ 5947038Sbostic #if !defined(cray) 6047038Sbostic #define LONG_IS_32_BITS 6147038Sbostic #endif 621958Swnj 631958Swnj /* 6447038Sbostic * define "B64" to be the declaration for a 64 bit integer. 6547038Sbostic * XXX this feature is currently unused, see "endian" comment below. 661958Swnj */ 6747038Sbostic #if defined(cray) 6847038Sbostic #define B64 long 6947038Sbostic #endif 7047038Sbostic #if defined(convex) 7147038Sbostic #define B64 long long 7247038Sbostic #endif 731958Swnj 741958Swnj /* 7547038Sbostic * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 7647038Sbostic * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 7748484Sbostic * little effect on crypt(). 781958Swnj */ 7947038Sbostic #if defined(notdef) 8047038Sbostic #define LARGEDATA 8147038Sbostic #endif 821958Swnj 8348484Sbostic /* compile with "-DSTATIC=int" when profiling */ 8448484Sbostic #ifndef STATIC 8547038Sbostic #define STATIC static 8648484Sbostic #endif 8748484Sbostic STATIC init_des(), init_perm(), permute(); 8847038Sbostic #ifdef DEBUG 8947038Sbostic STATIC prtab(); 9047038Sbostic #endif 911958Swnj 9247038Sbostic /* ==================================== */ 9347038Sbostic 941958Swnj /* 9547038Sbostic * Cipher-block representation (Bob Baldwin): 9647038Sbostic * 9747038Sbostic * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 9847038Sbostic * representation is to store one bit per byte in an array of bytes. Bit N of 9947038Sbostic * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 10047038Sbostic * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 10147038Sbostic * first byte, 9..16 in the second, and so on. The DES spec apparently has 10247038Sbostic * bit 1 in the MSB of the first byte, but that is particularly noxious so we 10347038Sbostic * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 10447038Sbostic * the MSB of the first byte. Specifically, the 64-bit input data and key are 10547038Sbostic * converted to LSB format, and the output 64-bit block is converted back into 10647038Sbostic * MSB format. 10747038Sbostic * 10847038Sbostic * DES operates internally on groups of 32 bits which are expanded to 48 bits 10947038Sbostic * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 11047038Sbostic * the computation, the expansion is applied only once, the expanded 11147038Sbostic * representation is maintained during the encryption, and a compression 11247038Sbostic * permutation is applied only at the end. To speed up the S-box lookups, 11347038Sbostic * the 48 bits are maintained as eight 6 bit groups, one per byte, which 11447038Sbostic * directly feed the eight S-boxes. Within each byte, the 6 bits are the 11547038Sbostic * most significant ones. The low two bits of each byte are zero. (Thus, 11647038Sbostic * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 11747038Sbostic * first byte in the eight byte representation, bit 2 of the 48 bit value is 11848484Sbostic * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 11947038Sbostic * used, in which the output is the 64 bit result of an S-box lookup which 12047038Sbostic * has been permuted by P and expanded by E, and is ready for use in the next 12147038Sbostic * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 12247038Sbostic * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 12347038Sbostic * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 12447038Sbostic * "salt" are also converted to this 8*(6+2) format. The SPE table size is 12547038Sbostic * 8*64*8 = 4K bytes. 12647038Sbostic * 12747038Sbostic * To speed up bit-parallel operations (such as XOR), the 8 byte 12847038Sbostic * representation is "union"ed with 32 bit values "i0" and "i1", and, on 12947038Sbostic * machines which support it, a 64 bit value "b64". This data structure, 13047038Sbostic * "C_block", has two problems. First, alignment restrictions must be 13147038Sbostic * honored. Second, the byte-order (e.g. little-endian or big-endian) of 13247038Sbostic * the architecture becomes visible. 13347038Sbostic * 13447038Sbostic * The byte-order problem is unfortunate, since on the one hand it is good 13547038Sbostic * to have a machine-independent C_block representation (bits 1..8 in the 13647038Sbostic * first byte, etc.), and on the other hand it is good for the LSB of the 13747038Sbostic * first byte to be the LSB of i0. We cannot have both these things, so we 13847038Sbostic * currently use the "little-endian" representation and avoid any multi-byte 13947038Sbostic * operations that depend on byte order. This largely precludes use of the 14047038Sbostic * 64-bit datatype since the relative order of i0 and i1 are unknown. It 14147038Sbostic * also inhibits grouping the SPE table to look up 12 bits at a time. (The 14247038Sbostic * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 14348484Sbostic * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 14447038Sbostic * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 14547038Sbostic * requires a 128 kilobyte table, so perhaps this is not a big loss. 14647038Sbostic * 14747038Sbostic * Permutation representation (Jim Gillogly): 14847038Sbostic * 14947038Sbostic * A transformation is defined by its effect on each of the 8 bytes of the 15047038Sbostic * 64-bit input. For each byte we give a 64-bit output that has the bits in 15147038Sbostic * the input distributed appropriately. The transformation is then the OR 15247038Sbostic * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 15347038Sbostic * each transformation. Unless LARGEDATA is defined, however, a more compact 15447038Sbostic * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 15547038Sbostic * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 15647038Sbostic * is slower but tolerable, particularly for password encryption in which 15747038Sbostic * the SPE transformation is iterated many times. The small tables total 9K 15847038Sbostic * bytes, the large tables total 72K bytes. 15947038Sbostic * 16047038Sbostic * The transformations used are: 16147038Sbostic * IE3264: MSB->LSB conversion, initial permutation, and expansion. 16247038Sbostic * This is done by collecting the 32 even-numbered bits and applying 16347038Sbostic * a 32->64 bit transformation, and then collecting the 32 odd-numbered 16447038Sbostic * bits and applying the same transformation. Since there are only 16547038Sbostic * 32 input bits, the IE3264 transformation table is half the size of 16647038Sbostic * the usual table. 16747038Sbostic * CF6464: Compression, final permutation, and LSB->MSB conversion. 16847038Sbostic * This is done by two trivial 48->32 bit compressions to obtain 16947038Sbostic * a 64-bit block (the bit numbering is given in the "CIFP" table) 17047038Sbostic * followed by a 64->64 bit "cleanup" transformation. (It would 17147038Sbostic * be possible to group the bits in the 64-bit block so that 2 17247038Sbostic * identical 32->32 bit transformations could be used instead, 17347038Sbostic * saving a factor of 4 in space and possibly 2 in time, but 17447038Sbostic * byte-ordering and other complications rear their ugly head. 17547038Sbostic * Similar opportunities/problems arise in the key schedule 17647038Sbostic * transforms.) 17747038Sbostic * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 17847038Sbostic * This admittedly baroque 64->64 bit transformation is used to 17947038Sbostic * produce the first code (in 8*(6+2) format) of the key schedule. 18047038Sbostic * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 18147038Sbostic * It would be possible to define 15 more transformations, each 18247038Sbostic * with a different rotation, to generate the entire key schedule. 18347038Sbostic * To save space, however, we instead permute each code into the 18447038Sbostic * next by using a transformation that "undoes" the PC2 permutation, 18547038Sbostic * rotates the code, and then applies PC2. Unfortunately, PC2 18647038Sbostic * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 18747038Sbostic * invertible. We get around that problem by using a modified PC2 18847038Sbostic * which retains the 8 otherwise-lost bits in the unused low-order 18947038Sbostic * bits of each byte. The low-order bits are cleared when the 19047038Sbostic * codes are stored into the key schedule. 19147038Sbostic * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 19247038Sbostic * This is faster than applying PC2ROT[0] twice, 19347038Sbostic * 19447038Sbostic * The Bell Labs "salt" (Bob Baldwin): 19547038Sbostic * 19647038Sbostic * The salting is a simple permutation applied to the 48-bit result of E. 19747038Sbostic * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 19847038Sbostic * i+24 of the result are swapped. The salt is thus a 24 bit number, with 19947038Sbostic * 16777216 possible values. (The original salt was 12 bits and could not 20047038Sbostic * swap bits 13..24 with 36..48.) 20147038Sbostic * 20248484Sbostic * It is possible, but ugly, to warp the SPE table to account for the salt 20348484Sbostic * permutation. Fortunately, the conditional bit swapping requires only 20448484Sbostic * about four machine instructions and can be done on-the-fly with about an 20548484Sbostic * 8% performance penalty. 2061958Swnj */ 20748484Sbostic 20847038Sbostic typedef union { 20947038Sbostic unsigned char b[8]; 21047038Sbostic struct { 21147038Sbostic #if defined(LONG_IS_32_BITS) 21247038Sbostic /* long is often faster than a 32-bit bit field */ 21347038Sbostic long i0; 21447038Sbostic long i1; 21547038Sbostic #else 21647038Sbostic long i0: 32; 21747038Sbostic long i1: 32; 21847038Sbostic #endif 21947038Sbostic } b32; 22047038Sbostic #if defined(B64) 22147038Sbostic B64 b64; 22247038Sbostic #endif 22347038Sbostic } C_block; 2241958Swnj 2251958Swnj /* 22647038Sbostic * Convert twenty-four-bit long in host-order 22747038Sbostic * to six bits (and 2 low-order zeroes) per char little-endian format. 2281958Swnj */ 22947038Sbostic #define TO_SIX_BIT(rslt, src) { \ 23047038Sbostic C_block cvt; \ 23147038Sbostic cvt.b[0] = src; src >>= 6; \ 23247038Sbostic cvt.b[1] = src; src >>= 6; \ 23347038Sbostic cvt.b[2] = src; src >>= 6; \ 23447038Sbostic cvt.b[3] = src; \ 23547038Sbostic rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 23647038Sbostic } 2371958Swnj 2381958Swnj /* 23947038Sbostic * These macros may someday permit efficient use of 64-bit integers. 24017337Sralph */ 24147038Sbostic #define ZERO(d,d0,d1) d0 = 0, d1 = 0 24247038Sbostic #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 24347038Sbostic #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 24447038Sbostic #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 24547038Sbostic #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 24647038Sbostic #define DCL_BLOCK(d,d0,d1) long d0, d1 24747038Sbostic 24847038Sbostic #if defined(LARGEDATA) 24947038Sbostic /* Waste memory like crazy. Also, do permutations in line */ 25047038Sbostic #define LGCHUNKBITS 3 25147038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 25247038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 25347038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 25447038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 25547038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 25647038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \ 25747038Sbostic OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 25847038Sbostic OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 25947038Sbostic OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 26047038Sbostic OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 26147038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 26247038Sbostic LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 26347038Sbostic OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 26447038Sbostic OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 26547038Sbostic OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 26647038Sbostic #else 26747038Sbostic /* "small data" */ 26847038Sbostic #define LGCHUNKBITS 2 26947038Sbostic #define CHUNKBITS (1<<LGCHUNKBITS) 27047038Sbostic #define PERM6464(d,d0,d1,cpp,p) \ 27147038Sbostic { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 27247038Sbostic #define PERM3264(d,d0,d1,cpp,p) \ 27347038Sbostic { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 27447038Sbostic 27547038Sbostic STATIC 27647038Sbostic permute(cp, out, p, chars_in) 27747038Sbostic unsigned char *cp; 27847038Sbostic C_block *out; 27947038Sbostic register C_block *p; 28047038Sbostic int chars_in; 28147038Sbostic { 28247038Sbostic register DCL_BLOCK(D,D0,D1); 28347038Sbostic register C_block *tp; 28447038Sbostic register int t; 28547038Sbostic 28647038Sbostic ZERO(D,D0,D1); 28747038Sbostic do { 28847038Sbostic t = *cp++; 28947038Sbostic tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 29047038Sbostic tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 29147038Sbostic } while (--chars_in > 0); 29247038Sbostic STORE(D,D0,D1,*out); 29347038Sbostic } 29447038Sbostic #endif /* LARGEDATA */ 29547038Sbostic 29647038Sbostic 29747038Sbostic /* ===== (mostly) Standard DES Tables ==================== */ 29847038Sbostic 29947038Sbostic static unsigned char IP[] = { /* initial permutation */ 30047038Sbostic 58, 50, 42, 34, 26, 18, 10, 2, 30147038Sbostic 60, 52, 44, 36, 28, 20, 12, 4, 30247038Sbostic 62, 54, 46, 38, 30, 22, 14, 6, 30347038Sbostic 64, 56, 48, 40, 32, 24, 16, 8, 30447038Sbostic 57, 49, 41, 33, 25, 17, 9, 1, 30547038Sbostic 59, 51, 43, 35, 27, 19, 11, 3, 30647038Sbostic 61, 53, 45, 37, 29, 21, 13, 5, 30747038Sbostic 63, 55, 47, 39, 31, 23, 15, 7, 30817337Sralph }; 30917337Sralph 31047038Sbostic /* The final permutation is the inverse of IP - no table is necessary */ 31147038Sbostic 31247038Sbostic static unsigned char ExpandTr[] = { /* expansion operation */ 31347038Sbostic 32, 1, 2, 3, 4, 5, 31447038Sbostic 4, 5, 6, 7, 8, 9, 31547038Sbostic 8, 9, 10, 11, 12, 13, 31647038Sbostic 12, 13, 14, 15, 16, 17, 31747038Sbostic 16, 17, 18, 19, 20, 21, 31847038Sbostic 20, 21, 22, 23, 24, 25, 31947038Sbostic 24, 25, 26, 27, 28, 29, 32047038Sbostic 28, 29, 30, 31, 32, 1, 32147038Sbostic }; 32247038Sbostic 32347038Sbostic static unsigned char PC1[] = { /* permuted choice table (key) */ 32447038Sbostic 57, 49, 41, 33, 25, 17, 9, 32547038Sbostic 1, 58, 50, 42, 34, 26, 18, 32647038Sbostic 10, 2, 59, 51, 43, 35, 27, 32747038Sbostic 19, 11, 3, 60, 52, 44, 36, 32847038Sbostic 32947038Sbostic 63, 55, 47, 39, 31, 23, 15, 33047038Sbostic 7, 62, 54, 46, 38, 30, 22, 33147038Sbostic 14, 6, 61, 53, 45, 37, 29, 33247038Sbostic 21, 13, 5, 28, 20, 12, 4, 33347038Sbostic }; 33447038Sbostic 33547038Sbostic static unsigned char Rotates[] = { /* number of rotations of PC1 */ 33647038Sbostic 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 33747038Sbostic }; 33847038Sbostic 33947038Sbostic /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 34047038Sbostic static unsigned char PC2[] = { /* permuted choice key (table) */ 34147038Sbostic 9, 18, 14, 17, 11, 24, 1, 5, 34247038Sbostic 22, 25, 3, 28, 15, 6, 21, 10, 34347038Sbostic 35, 38, 23, 19, 12, 4, 26, 8, 34447038Sbostic 43, 54, 16, 7, 27, 20, 13, 2, 34547038Sbostic 34647038Sbostic 0, 0, 41, 52, 31, 37, 47, 55, 34747038Sbostic 0, 0, 30, 40, 51, 45, 33, 48, 34847038Sbostic 0, 0, 44, 49, 39, 56, 34, 53, 34947038Sbostic 0, 0, 46, 42, 50, 36, 29, 32, 35047038Sbostic }; 35147038Sbostic 35247038Sbostic static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 35347038Sbostic /* S[1] */ 35447038Sbostic 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 35547038Sbostic 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 35647038Sbostic 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 35747038Sbostic 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 35847038Sbostic /* S[2] */ 35947038Sbostic 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 36047038Sbostic 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 36147038Sbostic 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 36247038Sbostic 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 36347038Sbostic /* S[3] */ 36447038Sbostic 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 36547038Sbostic 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 36647038Sbostic 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 36747038Sbostic 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 36847038Sbostic /* S[4] */ 36947038Sbostic 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 37047038Sbostic 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 37147038Sbostic 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 37247038Sbostic 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 37347038Sbostic /* S[5] */ 37447038Sbostic 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 37547038Sbostic 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 37647038Sbostic 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 37747038Sbostic 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 37847038Sbostic /* S[6] */ 37947038Sbostic 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 38047038Sbostic 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 38147038Sbostic 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 38247038Sbostic 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 38347038Sbostic /* S[7] */ 38447038Sbostic 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 38547038Sbostic 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 38647038Sbostic 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 38747038Sbostic 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 38847038Sbostic /* S[8] */ 38947038Sbostic 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 39047038Sbostic 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 39147038Sbostic 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 39247038Sbostic 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 39347038Sbostic }; 39447038Sbostic 39547038Sbostic static unsigned char P32Tr[] = { /* 32-bit permutation function */ 39647038Sbostic 16, 7, 20, 21, 39747038Sbostic 29, 12, 28, 17, 39847038Sbostic 1, 15, 23, 26, 39947038Sbostic 5, 18, 31, 10, 40047038Sbostic 2, 8, 24, 14, 40147038Sbostic 32, 27, 3, 9, 40247038Sbostic 19, 13, 30, 6, 40347038Sbostic 22, 11, 4, 25, 40447038Sbostic }; 40547038Sbostic 40647038Sbostic static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 40747038Sbostic 1, 2, 3, 4, 17, 18, 19, 20, 40847038Sbostic 5, 6, 7, 8, 21, 22, 23, 24, 40947038Sbostic 9, 10, 11, 12, 25, 26, 27, 28, 41047038Sbostic 13, 14, 15, 16, 29, 30, 31, 32, 41147038Sbostic 41247038Sbostic 33, 34, 35, 36, 49, 50, 51, 52, 41347038Sbostic 37, 38, 39, 40, 53, 54, 55, 56, 41447038Sbostic 41, 42, 43, 44, 57, 58, 59, 60, 41547038Sbostic 45, 46, 47, 48, 61, 62, 63, 64, 41647038Sbostic }; 41747038Sbostic 41847038Sbostic static unsigned char itoa64[] = /* 0..63 => ascii-64 */ 41947038Sbostic "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 42047038Sbostic 42147038Sbostic 42247038Sbostic /* ===== Tables that are initialized at run time ==================== */ 42347038Sbostic 42447038Sbostic 42547038Sbostic static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ 42647038Sbostic 42747038Sbostic /* Initial key schedule permutation */ 42847038Sbostic static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 42947038Sbostic 43047038Sbostic /* Subsequent key schedule rotation permutations */ 43147038Sbostic static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 43247038Sbostic 43347038Sbostic /* Initial permutation/expansion table */ 43447038Sbostic static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 43547038Sbostic 43647038Sbostic /* Table that combines the S, P, and E operations. */ 43747038Sbostic static long SPE[2][8][64]; 43847038Sbostic 43947038Sbostic /* compressed/interleaved => final permutation table */ 44047038Sbostic static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 44147038Sbostic 44247038Sbostic 44347038Sbostic /* ==================================== */ 44447038Sbostic 44547038Sbostic 44647038Sbostic static C_block constdatablock; /* encryption constant */ 44747038Sbostic static char cryptresult[1+4+4+11+1]; /* encrypted result */ 44847038Sbostic 44917337Sralph /* 45048484Sbostic * Return a pointer to static data consisting of the "setting" 45148484Sbostic * followed by an encryption produced by the "key" and "setting". 4521958Swnj */ 45347038Sbostic char * 45447038Sbostic crypt(key, setting) 45547038Sbostic register const char *key; 45647038Sbostic register const char *setting; 4571958Swnj { 45847038Sbostic register char *encp; 45947038Sbostic register long i; 46048484Sbostic register int t; 46147038Sbostic long salt; 46247038Sbostic int num_iter, salt_size, key_size; 46347038Sbostic C_block keyblock, rsltblock; 4641958Swnj 46548484Sbostic for (i = 0; i < 8; i++) { 46648484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 46747038Sbostic key++; 46848484Sbostic keyblock.b[i] = t; 46948484Sbostic } 47047038Sbostic des_setkey((char *)keyblock.b); /* also initializes "a64toi" */ 47147038Sbostic 47247038Sbostic encp = &cryptresult[0]; 473*48485Sbostic switch (*setting) { 474*48485Sbostic case _PASSWORD_EFMT1: 47547038Sbostic *encp++ = *setting++; 47647038Sbostic 47747038Sbostic /* get iteration count */ 47847038Sbostic num_iter = 0; 47947038Sbostic for (i = 4; --i >= 0; ) { 48048484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 48148484Sbostic t = '.'; 48248484Sbostic encp[i] = t; 48348484Sbostic num_iter = (num_iter<<6) | a64toi[t]; 48447038Sbostic } 48547038Sbostic setting += 4; 48647038Sbostic encp += 4; 48747038Sbostic salt_size = 4; 48847038Sbostic key_size = 128; 489*48485Sbostic break; 490*48485Sbostic default: 491*48485Sbostic num_iter = 25; 492*48485Sbostic salt_size = 2; 493*48485Sbostic key_size = 8; 49447038Sbostic } 49547038Sbostic 49647038Sbostic salt = 0; 49747038Sbostic for (i = salt_size; --i >= 0; ) { 49848484Sbostic if ((t = (unsigned char)setting[i]) == '\0') 49948484Sbostic t = '.'; 50048484Sbostic encp[i] = t; 50148484Sbostic salt = (salt<<6) | a64toi[t]; 50247038Sbostic } 50347038Sbostic encp += salt_size; 50447038Sbostic des_cipher((char *)&constdatablock, (char *)&rsltblock, salt, num_iter); 50547038Sbostic 5061958Swnj /* 50747038Sbostic * encrypt the remainder of the password 8 characters at a time. 5081958Swnj */ 50947038Sbostic while ((key_size -= 8) > 0 && *key) { 51047038Sbostic C_block xdatablock; 51147038Sbostic 51248484Sbostic for (i = 0; i < 8; i++) { 51348484Sbostic if ((t = 2*(unsigned char)(*key)) != 0) 51447038Sbostic key++; 51548484Sbostic keyblock.b[i] = t; 51648484Sbostic if (t == 0) 51747038Sbostic break; /* pad out with previous key */ 51848484Sbostic } 51947038Sbostic des_setkey((char *)keyblock.b); 52047038Sbostic des_cipher((char *)&constdatablock, (char *)&xdatablock, 0L, 1); 52147038Sbostic rsltblock.b32.i0 ^= xdatablock.b32.i0; 52247038Sbostic rsltblock.b32.i1 ^= xdatablock.b32.i1; 5231958Swnj } 52447038Sbostic 5251958Swnj /* 52647038Sbostic * Encode the 64 cipher bits as 11 ascii characters. 5271958Swnj */ 52847038Sbostic i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2]; 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[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5]; 53447038Sbostic encp[3] = itoa64[i&0x3f]; i >>= 6; 53547038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 53647038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 53747038Sbostic encp[0] = itoa64[i]; encp += 4; 53847038Sbostic i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 53947038Sbostic encp[2] = itoa64[i&0x3f]; i >>= 6; 54047038Sbostic encp[1] = itoa64[i&0x3f]; i >>= 6; 54147038Sbostic encp[0] = itoa64[i]; 54247038Sbostic 54347038Sbostic encp[3] = 0; 54448484Sbostic 54547038Sbostic return(cryptresult); 54647038Sbostic } 54747038Sbostic 54847038Sbostic 54947038Sbostic /* 55047038Sbostic * The Key Schedule, filled in by des_setkey() or setkey(). 55147038Sbostic */ 55247038Sbostic #define KS_SIZE 16 55347038Sbostic static C_block KS[KS_SIZE]; 55447038Sbostic 55547038Sbostic /* 55647038Sbostic * Set up the key schedule from the key. 55747038Sbostic */ 55847038Sbostic void 55947038Sbostic des_setkey(key) 56047038Sbostic register const char *key; 56147038Sbostic { 56247038Sbostic register DCL_BLOCK(K, K0, K1); 56347038Sbostic register C_block *ptabp; 56447038Sbostic register int i; 56547038Sbostic static int des_ready = 0; 56647038Sbostic 56747038Sbostic if (!des_ready) { 56847038Sbostic init_des(); 56947038Sbostic des_ready = 1; 5701958Swnj } 57117337Sralph 57247038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); 57347038Sbostic key = (char *)&KS[0]; 57447038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 57547038Sbostic for (i = 1; i < 16; i++) { 57647038Sbostic key += sizeof(C_block); 57747038Sbostic STORE(K,K0,K1,*(C_block *)key); 57847038Sbostic ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 57947038Sbostic PERM6464(K,K0,K1,(unsigned char *)key,ptabp); 58047038Sbostic STORE(K&0xfcfcfcfcL, K0&0xfcfcfcfcL, K1, *(C_block *)key); 58147038Sbostic } 5821958Swnj } 5831958Swnj 5841958Swnj /* 58547038Sbostic * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 58647038Sbostic * iterations of DES, using the the given 24-bit salt and the pre-computed key 58747038Sbostic * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 58847038Sbostic * 58947038Sbostic * NOTE: the performance of this routine is critically dependent on your 59047038Sbostic * compiler and machine architecture. 5911958Swnj */ 59247038Sbostic void 59347038Sbostic des_cipher(in, out, salt, num_iter) 59447038Sbostic const char *in; 59547038Sbostic char *out; 59648484Sbostic long salt; 59747038Sbostic int num_iter; 59847038Sbostic { 59947038Sbostic /* variables that we want in registers, most important first */ 60047038Sbostic #if defined(pdp11) 60147038Sbostic register int j; 60247038Sbostic #endif 60347038Sbostic register long L0, L1, R0, R1, k; 60447038Sbostic register C_block *kp; 60547038Sbostic register int ks_inc, loop_count; 60647038Sbostic C_block B; 6071958Swnj 60847038Sbostic L0 = salt; 60947038Sbostic TO_SIX_BIT(salt, L0); /* convert to 8*(6+2) format */ 6101958Swnj 61147038Sbostic #if defined(vax) || defined(pdp11) 61247038Sbostic salt = ~salt; /* "x &~ y" is faster than "x & y". */ 61347038Sbostic #define SALT (~salt) 61447038Sbostic #else 61547038Sbostic #define SALT salt 61647038Sbostic #endif 6171958Swnj 61847038Sbostic #if defined(MUST_ALIGN) 61947038Sbostic B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 62047038Sbostic B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 62147038Sbostic LOAD(L,L0,L1,B); 62247038Sbostic #else 62347038Sbostic LOAD(L,L0,L1,*(C_block *)in); 62447038Sbostic #endif 62547038Sbostic LOADREG(R,R0,R1,L,L0,L1); 62647038Sbostic L0 &= 0x55555555L; 62747038Sbostic L1 &= 0x55555555L; 62847038Sbostic L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ 62947038Sbostic R0 &= 0xaaaaaaaaL; 63047038Sbostic R1 = (R1 >> 1) & 0x55555555L; 63147038Sbostic L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 63247038Sbostic STORE(L,L0,L1,B); 63347038Sbostic PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 63447038Sbostic PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 6351958Swnj 63647038Sbostic if (num_iter >= 0) 63747038Sbostic { /* encryption */ 63847038Sbostic kp = &KS[0]; 63947038Sbostic ks_inc = sizeof(*kp); 64047038Sbostic } 64147038Sbostic else 64247038Sbostic { /* decryption */ 64347038Sbostic num_iter = -num_iter; 64447038Sbostic kp = &KS[KS_SIZE-1]; 64547038Sbostic ks_inc = -sizeof(*kp); 64647038Sbostic } 6471958Swnj 64847038Sbostic while (--num_iter >= 0) { 64947038Sbostic loop_count = 8; 65047038Sbostic do { 6511958Swnj 65247038Sbostic #define BTAB(i) (((unsigned char *)&B.b[0])[i]) 65347038Sbostic #define SPTAB(t, i) (*(long *)((unsigned char *)t \ 65447038Sbostic + i*(sizeof(long)/4))) 65547038Sbostic #if defined(gould) 65647038Sbostic /* use this if BTAB(i) is evaluated just once ... */ 65747038Sbostic #define DOXOR(a,b,i) a^=SPTAB(SPE[0][i],BTAB(i));b^=SPTAB(SPE[1][i],BTAB(i)); 65847038Sbostic #else 65947038Sbostic #if defined(pdp11) 66047038Sbostic /* use this if your "long" int indexing is slow */ 66147038Sbostic #define DOXOR(a,b,i) j=BTAB(i); a^=SPTAB(SPE[0][i],j); b^=SPTAB(SPE[1][i],j); 66247038Sbostic #else 66347038Sbostic /* use this if "k" is allocated to a register ... */ 66447038Sbostic #define DOXOR(a,b,i) k=BTAB(i); a^=SPTAB(SPE[0][i],k); b^=SPTAB(SPE[1][i],k); 66547038Sbostic #endif 66647038Sbostic #endif 6671958Swnj 66847038Sbostic #define CRUNCH(L0, L1, R0, R1) \ 66947038Sbostic k = (R0 ^ R1) & SALT; \ 67047038Sbostic B.b32.i0 = k ^ R0 ^ kp->b32.i0; \ 67147038Sbostic B.b32.i1 = k ^ R1 ^ kp->b32.i1; \ 67247038Sbostic kp = (C_block *)((char *)kp+ks_inc); \ 67347038Sbostic \ 67447038Sbostic DOXOR(L0, L1, 0); \ 67547038Sbostic DOXOR(L0, L1, 1); \ 67647038Sbostic DOXOR(L0, L1, 2); \ 67747038Sbostic DOXOR(L0, L1, 3); \ 67847038Sbostic DOXOR(L0, L1, 4); \ 67947038Sbostic DOXOR(L0, L1, 5); \ 68047038Sbostic DOXOR(L0, L1, 6); \ 68147038Sbostic DOXOR(L0, L1, 7); 6821958Swnj 68347038Sbostic CRUNCH(L0, L1, R0, R1); 68447038Sbostic CRUNCH(R0, R1, L0, L1); 68547038Sbostic } while (--loop_count != 0); 68647038Sbostic kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 6871958Swnj 6881958Swnj 68947038Sbostic /* swap L and R */ 69047038Sbostic L0 ^= R0; L1 ^= R1; 69147038Sbostic R0 ^= L0; R1 ^= L1; 69247038Sbostic L0 ^= R0; L1 ^= R1; 69347038Sbostic } 6941958Swnj 69547038Sbostic /* store the encrypted (or decrypted) result */ 69647038Sbostic L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); 69747038Sbostic L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); 69847038Sbostic STORE(L,L0,L1,B); 69947038Sbostic PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 70047038Sbostic #if defined(MUST_ALIGN) 70147038Sbostic STORE(L,L0,L1,B); 70247038Sbostic out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 70347038Sbostic out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 70447038Sbostic #else 70547038Sbostic STORE(L,L0,L1,*(C_block *)out); 70647038Sbostic #endif 70747038Sbostic } 70847038Sbostic 70947038Sbostic 7101958Swnj /* 71147038Sbostic * Initialize various tables. This need only be done once. It could even be 71247038Sbostic * done at compile time, if the compiler were capable of that sort of thing. 7131958Swnj */ 71447038Sbostic STATIC 71547038Sbostic init_des() 7161958Swnj { 71747038Sbostic register int i, j; 71847038Sbostic register long k; 71947038Sbostic register int tableno; 72047038Sbostic static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 7211958Swnj 7221958Swnj /* 72347038Sbostic * table that converts chars "./0-9A-Za-z"to integers 0-63. 7241958Swnj */ 72547038Sbostic for (i = 0; i < 64; i++) 72647038Sbostic a64toi[itoa64[i]] = i; 72747038Sbostic 7281958Swnj /* 72947038Sbostic * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 7301958Swnj */ 73147038Sbostic for (i = 0; i < 64; i++) 73247038Sbostic perm[i] = 0; 73347038Sbostic for (i = 0; i < 64; i++) { 73447038Sbostic if ((k = PC2[i]) == 0) 73547038Sbostic continue; 73647038Sbostic k += Rotates[0]-1; 73747038Sbostic if ((k%28) < Rotates[0]) k -= 28; 73847038Sbostic k = PC1[k]; 73947038Sbostic if (k > 0) { 74047038Sbostic k--; 74147038Sbostic k = (k|07) - (k&07); 74247038Sbostic k++; 7431958Swnj } 74447038Sbostic perm[i] = k; 7451958Swnj } 74647038Sbostic #ifdef DEBUG 74747038Sbostic prtab("pc1tab", perm, 8); 74847038Sbostic #endif 74948484Sbostic init_perm(PC1ROT, perm, 8, 8); 75047038Sbostic 7511958Swnj /* 75247038Sbostic * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 7531958Swnj */ 75447038Sbostic for (j = 0; j < 2; j++) { 75547038Sbostic unsigned char pc2inv[64]; 75647038Sbostic for (i = 0; i < 64; i++) 75747038Sbostic perm[i] = pc2inv[i] = 0; 75847038Sbostic for (i = 0; i < 64; i++) { 75947038Sbostic if ((k = PC2[i]) == 0) 76047038Sbostic continue; 76147038Sbostic pc2inv[k-1] = i+1; 76247038Sbostic } 76347038Sbostic for (i = 0; i < 64; i++) { 76447038Sbostic if ((k = PC2[i]) == 0) 76547038Sbostic continue; 76647038Sbostic k += j; 76747038Sbostic if ((k%28) <= j) k -= 28; 76847038Sbostic perm[i] = pc2inv[k]; 76947038Sbostic } 77047038Sbostic #ifdef DEBUG 77147038Sbostic prtab("pc2tab", perm, 8); 77247038Sbostic #endif 77348484Sbostic init_perm(PC2ROT[j], perm, 8, 8); 7741958Swnj } 77547038Sbostic 7761958Swnj /* 77747038Sbostic * Bit reverse, then initial permutation, then expansion. 7781958Swnj */ 77947038Sbostic for (i = 0; i < 8; i++) { 78047038Sbostic for (j = 0; j < 8; j++) { 78147038Sbostic k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 78247038Sbostic if (k > 32) 78347038Sbostic k -= 32; 78447038Sbostic else if (k > 0) 78547038Sbostic k--; 78647038Sbostic if (k > 0) { 78747038Sbostic k--; 78847038Sbostic k = (k|07) - (k&07); 78947038Sbostic k++; 79047038Sbostic } 79147038Sbostic perm[i*8+j] = k; 79247038Sbostic } 79347038Sbostic } 79447038Sbostic #ifdef DEBUG 79547038Sbostic prtab("ietab", perm, 8); 79647038Sbostic #endif 79748484Sbostic init_perm(IE3264, perm, 4, 8); 79847038Sbostic 79947038Sbostic /* 80047038Sbostic * Compression, then final permutation, then bit reverse. 80147038Sbostic */ 80247038Sbostic for (i = 0; i < 64; i++) { 80347038Sbostic k = IP[CIFP[i]-1]; 80447038Sbostic if (k > 0) { 80547038Sbostic k--; 80647038Sbostic k = (k|07) - (k&07); 80747038Sbostic k++; 80847038Sbostic } 80947038Sbostic perm[k-1] = i+1; 81047038Sbostic } 81147038Sbostic #ifdef DEBUG 81247038Sbostic prtab("cftab", perm, 8); 81347038Sbostic #endif 81448484Sbostic init_perm(CF6464, perm, 8, 8); 81547038Sbostic 81647038Sbostic /* 81747038Sbostic * SPE table 81847038Sbostic */ 81947038Sbostic for (i = 0; i < 48; i++) 82047038Sbostic perm[i] = P32Tr[ExpandTr[i]-1]; 82147038Sbostic for (tableno = 0; tableno < 8; tableno++) { 82247038Sbostic for (j = 0; j < 64; j++) { 82347038Sbostic k = (((j >> 0) &01) << 5)| 82447038Sbostic (((j >> 1) &01) << 3)| 82547038Sbostic (((j >> 2) &01) << 2)| 82647038Sbostic (((j >> 3) &01) << 1)| 82747038Sbostic (((j >> 4) &01) << 0)| 82847038Sbostic (((j >> 5) &01) << 4); 82947038Sbostic k = S[tableno][k]; 83047038Sbostic k = (((k >> 3)&01) << 0)| 83147038Sbostic (((k >> 2)&01) << 1)| 83247038Sbostic (((k >> 1)&01) << 2)| 83347038Sbostic (((k >> 0)&01) << 3); 83447038Sbostic for (i = 0; i < 32; i++) 83547038Sbostic tmp32[i] = 0; 83647038Sbostic for (i = 0; i < 4; i++) 83747038Sbostic tmp32[4 * tableno + i] = (k >> i) & 01; 83847038Sbostic k = 0; 83947038Sbostic for (i = 24; --i >= 0; ) 84047038Sbostic k = (k<<1) | tmp32[perm[i]-1]; 84147038Sbostic TO_SIX_BIT(SPE[0][tableno][j], k); 84247038Sbostic k = 0; 84347038Sbostic for (i = 24; --i >= 0; ) 84447038Sbostic k = (k<<1) | tmp32[perm[i+24]-1]; 84547038Sbostic TO_SIX_BIT(SPE[1][tableno][j], k); 84647038Sbostic } 84747038Sbostic } 8481958Swnj } 8491958Swnj 85047038Sbostic /* 85148484Sbostic * Initialize "perm" to represent transformation "p", which rearranges 85248484Sbostic * (perhaps with expansion and/or contraction) one packed array of bits 85348484Sbostic * (of size "chars_in" characters) into another array (of size "chars_out" 85448484Sbostic * characters). 85548484Sbostic * 85647038Sbostic * "perm" must be all-zeroes on entry to this routine. 85747038Sbostic */ 85847038Sbostic STATIC 85948484Sbostic init_perm(perm, p, chars_in, chars_out) 86047038Sbostic C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; 86147038Sbostic unsigned char p[64]; 86247038Sbostic int chars_in, chars_out; 8631958Swnj { 86447038Sbostic register int i, j, k, l; 86517337Sralph 86647038Sbostic for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 86747038Sbostic l = p[k] - 1; /* where this bit comes from */ 86847038Sbostic if (l < 0) 86947038Sbostic continue; /* output bit is always 0 */ 87047038Sbostic i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 87147038Sbostic l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 87247038Sbostic for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 87347038Sbostic if ((j & l) != 0) 87447038Sbostic perm[i][j].b[k>>3] |= 1<<(k&07); 87547038Sbostic } 8761958Swnj } 87747038Sbostic } 8781958Swnj 87947038Sbostic /* 88047038Sbostic * "setkey" routine (for backwards compatibility) 88147038Sbostic */ 88247038Sbostic void 88347038Sbostic setkey(key) 88447038Sbostic register const char *key; 88547038Sbostic { 88647038Sbostic register int i, j, k; 88747038Sbostic C_block keyblock; 88847038Sbostic 88947038Sbostic for (i = 0; i < 8; i++) { 89047038Sbostic k = 0; 89147038Sbostic for (j = 0; j < 8; j++) { 89247038Sbostic k <<= 1; 89347038Sbostic k |= (unsigned char)*key++; 8941958Swnj } 89547038Sbostic keyblock.b[i] = k; 8961958Swnj } 89747038Sbostic des_setkey((char *)keyblock.b); 8981958Swnj } 89947038Sbostic 90047038Sbostic /* 90147038Sbostic * "encrypt" routine (for backwards compatibility) 90247038Sbostic */ 90347038Sbostic void 90447038Sbostic encrypt(block, flag) 90547038Sbostic register char *block; 90647038Sbostic int flag; 90747038Sbostic { 90847038Sbostic register int i, j, k; 90947038Sbostic C_block cblock; 91047038Sbostic 91147038Sbostic for (i = 0; i < 8; i++) { 91247038Sbostic k = 0; 91347038Sbostic for (j = 0; j < 8; j++) { 91447038Sbostic k <<= 1; 91547038Sbostic k |= (unsigned char)*block++; 91647038Sbostic } 91747038Sbostic cblock.b[i] = k; 91847038Sbostic } 91947038Sbostic des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag? -1: 1)); 92047038Sbostic for (i = 7; i >= 0; i--) { 92147038Sbostic k = cblock.b[i]; 92247038Sbostic for (j = 7; j >= 0; j--) { 92347038Sbostic *--block = k&01; 92447038Sbostic k >>= 1; 92547038Sbostic } 92647038Sbostic } 92747038Sbostic } 92847038Sbostic 92947038Sbostic #ifdef DEBUG 93047038Sbostic STATIC 93147038Sbostic prtab(s, t, num_rows) 93247038Sbostic char *s; 93347038Sbostic unsigned char *t; 93447038Sbostic int num_rows; 93547038Sbostic { 93647038Sbostic register int i, j; 93747038Sbostic 938*48485Sbostic (void)printf("%s:\n", s); 93947038Sbostic for (i = 0; i < num_rows; i++) { 94047038Sbostic for (j = 0; j < 8; j++) { 941*48485Sbostic (void)printf("%3d", t[i*8+j]); 94247038Sbostic } 943*48485Sbostic (void)printf("\n"); 94447038Sbostic } 945*48485Sbostic (void)printf("\n"); 94647038Sbostic } 94747038Sbostic #endif 948