1*56545abaSkleink /* $NetBSD: crypt.c,v 1.12 1998/06/01 20:25:24 kleink Exp $ */ 24902ac3dScgd 3e0b9a84aScgd /* 44902ac3dScgd * Copyright (c) 1989, 1993 54902ac3dScgd * The Regents of the University of California. All rights reserved. 6e0b9a84aScgd * 7e0b9a84aScgd * This code is derived from software contributed to Berkeley by 8e0b9a84aScgd * Tom Truscott. 9e0b9a84aScgd * 10e0b9a84aScgd * Redistribution and use in source and binary forms, with or without 11e0b9a84aScgd * modification, are permitted provided that the following conditions 12e0b9a84aScgd * are met: 13e0b9a84aScgd * 1. Redistributions of source code must retain the above copyright 14e0b9a84aScgd * notice, this list of conditions and the following disclaimer. 15e0b9a84aScgd * 2. Redistributions in binary form must reproduce the above copyright 16e0b9a84aScgd * notice, this list of conditions and the following disclaimer in the 17e0b9a84aScgd * documentation and/or other materials provided with the distribution. 18e0b9a84aScgd * 3. All advertising materials mentioning features or use of this software 19e0b9a84aScgd * must display the following acknowledgement: 20e0b9a84aScgd * This product includes software developed by the University of 21e0b9a84aScgd * California, Berkeley and its contributors. 22e0b9a84aScgd * 4. Neither the name of the University nor the names of its contributors 23e0b9a84aScgd * may be used to endorse or promote products derived from this software 24e0b9a84aScgd * without specific prior written permission. 25e0b9a84aScgd * 26e0b9a84aScgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27e0b9a84aScgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28e0b9a84aScgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29e0b9a84aScgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30e0b9a84aScgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31e0b9a84aScgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32e0b9a84aScgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33e0b9a84aScgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34e0b9a84aScgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35e0b9a84aScgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36e0b9a84aScgd * SUCH DAMAGE. 37e0b9a84aScgd */ 38e0b9a84aScgd 3906795b86Slukem #include <sys/cdefs.h> 4006795b86Slukem #if !defined(lint) 414902ac3dScgd #if 0 424902ac3dScgd static char sccsid[] = "@(#)crypt.c 8.1.1.1 (Berkeley) 8/18/93"; 4306795b86Slukem #else 44*56545abaSkleink __RCSID("$NetBSD: crypt.c,v 1.12 1998/06/01 20:25:24 kleink Exp $"); 454902ac3dScgd #endif 4606795b86Slukem #endif /* not lint */ 47e0b9a84aScgd 48e0b9a84aScgd #include <limits.h> 49e0b9a84aScgd #include <pwd.h> 50*56545abaSkleink #include <stdlib.h> 5131a2bdc6Smikel #include <unistd.h> 52e0b9a84aScgd 53e0b9a84aScgd /* 54e0b9a84aScgd * UNIX password, and DES, encryption. 55e0b9a84aScgd * By Tom Truscott, trt@rti.rti.org, 56e0b9a84aScgd * from algorithms by Robert W. Baldwin and James Gillogly. 57e0b9a84aScgd * 58e0b9a84aScgd * References: 59e0b9a84aScgd * "Mathematical Cryptology for Computer Scientists and Mathematicians," 60e0b9a84aScgd * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 61e0b9a84aScgd * 62e0b9a84aScgd * "Password Security: A Case History," R. Morris and Ken Thompson, 63e0b9a84aScgd * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 64e0b9a84aScgd * 65e0b9a84aScgd * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 66e0b9a84aScgd * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 67e0b9a84aScgd */ 68e0b9a84aScgd 69e0b9a84aScgd /* ===== Configuration ==================== */ 70e0b9a84aScgd 71e0b9a84aScgd /* 72e0b9a84aScgd * define "MUST_ALIGN" if your compiler cannot load/store 73e0b9a84aScgd * long integers at arbitrary (e.g. odd) memory locations. 74e0b9a84aScgd * (Either that or never pass unaligned addresses to des_cipher!) 75e0b9a84aScgd */ 76e0b9a84aScgd #if !defined(vax) 77e0b9a84aScgd #define MUST_ALIGN 78e0b9a84aScgd #endif 79e0b9a84aScgd 80e0b9a84aScgd #ifdef CHAR_BITS 81e0b9a84aScgd #if CHAR_BITS != 8 82e0b9a84aScgd #error C_block structure assumes 8 bit characters 83e0b9a84aScgd #endif 84e0b9a84aScgd #endif 85e0b9a84aScgd 86e0b9a84aScgd /* 87e0b9a84aScgd * define "B64" to be the declaration for a 64 bit integer. 88e0b9a84aScgd * XXX this feature is currently unused, see "endian" comment below. 89e0b9a84aScgd */ 90e0b9a84aScgd #if defined(cray) 91e0b9a84aScgd #define B64 long 92e0b9a84aScgd #endif 93e0b9a84aScgd #if defined(convex) 94e0b9a84aScgd #define B64 long long 95e0b9a84aScgd #endif 96e0b9a84aScgd 97e0b9a84aScgd /* 98e0b9a84aScgd * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 99e0b9a84aScgd * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 100e0b9a84aScgd * little effect on crypt(). 101e0b9a84aScgd */ 102e0b9a84aScgd #if defined(notdef) 103e0b9a84aScgd #define LARGEDATA 104e0b9a84aScgd #endif 105e0b9a84aScgd 10631a2bdc6Smikel /* compile with "-DSTATIC=void" when profiling */ 107e0b9a84aScgd #ifndef STATIC 10831a2bdc6Smikel #define STATIC static void 109e0b9a84aScgd #endif 110e0b9a84aScgd 111e0b9a84aScgd /* ==================================== */ 112e0b9a84aScgd 113e0b9a84aScgd /* 114e0b9a84aScgd * Cipher-block representation (Bob Baldwin): 115e0b9a84aScgd * 116e0b9a84aScgd * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 117e0b9a84aScgd * representation is to store one bit per byte in an array of bytes. Bit N of 118e0b9a84aScgd * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 119e0b9a84aScgd * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 120e0b9a84aScgd * first byte, 9..16 in the second, and so on. The DES spec apparently has 121e0b9a84aScgd * bit 1 in the MSB of the first byte, but that is particularly noxious so we 122e0b9a84aScgd * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 123e0b9a84aScgd * the MSB of the first byte. Specifically, the 64-bit input data and key are 124e0b9a84aScgd * converted to LSB format, and the output 64-bit block is converted back into 125e0b9a84aScgd * MSB format. 126e0b9a84aScgd * 127e0b9a84aScgd * DES operates internally on groups of 32 bits which are expanded to 48 bits 128e0b9a84aScgd * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 129e0b9a84aScgd * the computation, the expansion is applied only once, the expanded 130e0b9a84aScgd * representation is maintained during the encryption, and a compression 131e0b9a84aScgd * permutation is applied only at the end. To speed up the S-box lookups, 132e0b9a84aScgd * the 48 bits are maintained as eight 6 bit groups, one per byte, which 133e0b9a84aScgd * directly feed the eight S-boxes. Within each byte, the 6 bits are the 134e0b9a84aScgd * most significant ones. The low two bits of each byte are zero. (Thus, 135e0b9a84aScgd * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 136e0b9a84aScgd * first byte in the eight byte representation, bit 2 of the 48 bit value is 137e0b9a84aScgd * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 138e0b9a84aScgd * used, in which the output is the 64 bit result of an S-box lookup which 139e0b9a84aScgd * has been permuted by P and expanded by E, and is ready for use in the next 140e0b9a84aScgd * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 141e0b9a84aScgd * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 142e0b9a84aScgd * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 143e0b9a84aScgd * "salt" are also converted to this 8*(6+2) format. The SPE table size is 144e0b9a84aScgd * 8*64*8 = 4K bytes. 145e0b9a84aScgd * 146e0b9a84aScgd * To speed up bit-parallel operations (such as XOR), the 8 byte 147e0b9a84aScgd * representation is "union"ed with 32 bit values "i0" and "i1", and, on 148e0b9a84aScgd * machines which support it, a 64 bit value "b64". This data structure, 149e0b9a84aScgd * "C_block", has two problems. First, alignment restrictions must be 150e0b9a84aScgd * honored. Second, the byte-order (e.g. little-endian or big-endian) of 151e0b9a84aScgd * the architecture becomes visible. 152e0b9a84aScgd * 153e0b9a84aScgd * The byte-order problem is unfortunate, since on the one hand it is good 154e0b9a84aScgd * to have a machine-independent C_block representation (bits 1..8 in the 155e0b9a84aScgd * first byte, etc.), and on the other hand it is good for the LSB of the 156e0b9a84aScgd * first byte to be the LSB of i0. We cannot have both these things, so we 157e0b9a84aScgd * currently use the "little-endian" representation and avoid any multi-byte 158e0b9a84aScgd * operations that depend on byte order. This largely precludes use of the 159e0b9a84aScgd * 64-bit datatype since the relative order of i0 and i1 are unknown. It 160e0b9a84aScgd * also inhibits grouping the SPE table to look up 12 bits at a time. (The 161e0b9a84aScgd * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 162e0b9a84aScgd * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 163e0b9a84aScgd * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 164e0b9a84aScgd * requires a 128 kilobyte table, so perhaps this is not a big loss. 165e0b9a84aScgd * 166e0b9a84aScgd * Permutation representation (Jim Gillogly): 167e0b9a84aScgd * 168e0b9a84aScgd * A transformation is defined by its effect on each of the 8 bytes of the 169e0b9a84aScgd * 64-bit input. For each byte we give a 64-bit output that has the bits in 170e0b9a84aScgd * the input distributed appropriately. The transformation is then the OR 171e0b9a84aScgd * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 172e0b9a84aScgd * each transformation. Unless LARGEDATA is defined, however, a more compact 173e0b9a84aScgd * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 174e0b9a84aScgd * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 175e0b9a84aScgd * is slower but tolerable, particularly for password encryption in which 176e0b9a84aScgd * the SPE transformation is iterated many times. The small tables total 9K 177e0b9a84aScgd * bytes, the large tables total 72K bytes. 178e0b9a84aScgd * 179e0b9a84aScgd * The transformations used are: 180e0b9a84aScgd * IE3264: MSB->LSB conversion, initial permutation, and expansion. 181e0b9a84aScgd * This is done by collecting the 32 even-numbered bits and applying 182e0b9a84aScgd * a 32->64 bit transformation, and then collecting the 32 odd-numbered 183e0b9a84aScgd * bits and applying the same transformation. Since there are only 184e0b9a84aScgd * 32 input bits, the IE3264 transformation table is half the size of 185e0b9a84aScgd * the usual table. 186e0b9a84aScgd * CF6464: Compression, final permutation, and LSB->MSB conversion. 187e0b9a84aScgd * This is done by two trivial 48->32 bit compressions to obtain 188e0b9a84aScgd * a 64-bit block (the bit numbering is given in the "CIFP" table) 189e0b9a84aScgd * followed by a 64->64 bit "cleanup" transformation. (It would 190e0b9a84aScgd * be possible to group the bits in the 64-bit block so that 2 191e0b9a84aScgd * identical 32->32 bit transformations could be used instead, 192e0b9a84aScgd * saving a factor of 4 in space and possibly 2 in time, but 193e0b9a84aScgd * byte-ordering and other complications rear their ugly head. 194e0b9a84aScgd * Similar opportunities/problems arise in the key schedule 195e0b9a84aScgd * transforms.) 196e0b9a84aScgd * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 197e0b9a84aScgd * This admittedly baroque 64->64 bit transformation is used to 198e0b9a84aScgd * produce the first code (in 8*(6+2) format) of the key schedule. 199e0b9a84aScgd * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 200e0b9a84aScgd * It would be possible to define 15 more transformations, each 201e0b9a84aScgd * with a different rotation, to generate the entire key schedule. 202e0b9a84aScgd * To save space, however, we instead permute each code into the 203e0b9a84aScgd * next by using a transformation that "undoes" the PC2 permutation, 204e0b9a84aScgd * rotates the code, and then applies PC2. Unfortunately, PC2 205e0b9a84aScgd * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 206e0b9a84aScgd * invertible. We get around that problem by using a modified PC2 207e0b9a84aScgd * which retains the 8 otherwise-lost bits in the unused low-order 208e0b9a84aScgd * bits of each byte. The low-order bits are cleared when the 209e0b9a84aScgd * codes are stored into the key schedule. 210e0b9a84aScgd * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 211e0b9a84aScgd * This is faster than applying PC2ROT[0] twice, 212e0b9a84aScgd * 213e0b9a84aScgd * The Bell Labs "salt" (Bob Baldwin): 214e0b9a84aScgd * 215e0b9a84aScgd * The salting is a simple permutation applied to the 48-bit result of E. 216e0b9a84aScgd * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 217e0b9a84aScgd * i+24 of the result are swapped. The salt is thus a 24 bit number, with 218e0b9a84aScgd * 16777216 possible values. (The original salt was 12 bits and could not 219e0b9a84aScgd * swap bits 13..24 with 36..48.) 220e0b9a84aScgd * 221e0b9a84aScgd * It is possible, but ugly, to warp the SPE table to account for the salt 222e0b9a84aScgd * permutation. Fortunately, the conditional bit swapping requires only 223e0b9a84aScgd * about four machine instructions and can be done on-the-fly with about an 224e0b9a84aScgd * 8% performance penalty. 225e0b9a84aScgd */ 226e0b9a84aScgd 227e0b9a84aScgd typedef union { 228e0b9a84aScgd unsigned char b[8]; 229e0b9a84aScgd struct { 230688980ebScgd int32_t i0; 231688980ebScgd int32_t i1; 232e0b9a84aScgd } b32; 233e0b9a84aScgd #if defined(B64) 234e0b9a84aScgd B64 b64; 235e0b9a84aScgd #endif 236e0b9a84aScgd } C_block; 237e0b9a84aScgd 238e0b9a84aScgd /* 239e0b9a84aScgd * Convert twenty-four-bit long in host-order 240e0b9a84aScgd * to six bits (and 2 low-order zeroes) per char little-endian format. 241e0b9a84aScgd */ 242e0b9a84aScgd #define TO_SIX_BIT(rslt, src) { \ 243e0b9a84aScgd C_block cvt; \ 244e0b9a84aScgd cvt.b[0] = src; src >>= 6; \ 245e0b9a84aScgd cvt.b[1] = src; src >>= 6; \ 246e0b9a84aScgd cvt.b[2] = src; src >>= 6; \ 247e0b9a84aScgd cvt.b[3] = src; \ 248e0b9a84aScgd rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 249e0b9a84aScgd } 250e0b9a84aScgd 251e0b9a84aScgd /* 252e0b9a84aScgd * These macros may someday permit efficient use of 64-bit integers. 253e0b9a84aScgd */ 254e0b9a84aScgd #define ZERO(d,d0,d1) d0 = 0, d1 = 0 255e0b9a84aScgd #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 256e0b9a84aScgd #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 257e0b9a84aScgd #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 258e0b9a84aScgd #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 259688980ebScgd #define DCL_BLOCK(d,d0,d1) int32_t d0, d1 260e0b9a84aScgd 261e0b9a84aScgd #if defined(LARGEDATA) 262e0b9a84aScgd /* Waste memory like crazy. Also, do permutations in line */ 263e0b9a84aScgd #define LGCHUNKBITS 3 264e0b9a84aScgd #define CHUNKBITS (1<<LGCHUNKBITS) 265e0b9a84aScgd #define PERM6464(d,d0,d1,cpp,p) \ 266e0b9a84aScgd LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 267e0b9a84aScgd OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 268e0b9a84aScgd OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 269e0b9a84aScgd OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \ 270e0b9a84aScgd OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 271e0b9a84aScgd OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 272e0b9a84aScgd OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 273e0b9a84aScgd OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 274e0b9a84aScgd #define PERM3264(d,d0,d1,cpp,p) \ 275e0b9a84aScgd LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 276e0b9a84aScgd OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 277e0b9a84aScgd OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 278e0b9a84aScgd OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 279e0b9a84aScgd #else 280e0b9a84aScgd /* "small data" */ 281e0b9a84aScgd #define LGCHUNKBITS 2 282e0b9a84aScgd #define CHUNKBITS (1<<LGCHUNKBITS) 283e0b9a84aScgd #define PERM6464(d,d0,d1,cpp,p) \ 284e0b9a84aScgd { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 285e0b9a84aScgd #define PERM3264(d,d0,d1,cpp,p) \ 286e0b9a84aScgd { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 287cd0a22a4Smikel #endif /* LARGEDATA */ 28806795b86Slukem 28906795b86Slukem STATIC init_des __P((void)); 290226f67d0Scgd STATIC init_perm __P((C_block [64/CHUNKBITS][1<<CHUNKBITS], unsigned char [64], int, int)); 291cd0a22a4Smikel #ifndef LARGEDATA 29206795b86Slukem STATIC permute __P((unsigned char *, C_block *, C_block *, int)); 293cd0a22a4Smikel #endif 29406795b86Slukem #ifdef DEBUG 29506795b86Slukem STATIC prtab __P((char *, unsigned char *, int)); 29606795b86Slukem #endif 29706795b86Slukem 29806795b86Slukem 299cd0a22a4Smikel #ifndef LARGEDATA 300e0b9a84aScgd STATIC 301e0b9a84aScgd permute(cp, out, p, chars_in) 302e0b9a84aScgd unsigned char *cp; 303e0b9a84aScgd C_block *out; 30406795b86Slukem C_block *p; 305e0b9a84aScgd int chars_in; 306e0b9a84aScgd { 30706795b86Slukem DCL_BLOCK(D,D0,D1); 30806795b86Slukem C_block *tp; 30906795b86Slukem int t; 310e0b9a84aScgd 311e0b9a84aScgd ZERO(D,D0,D1); 312e0b9a84aScgd do { 313e0b9a84aScgd t = *cp++; 314e0b9a84aScgd tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 315e0b9a84aScgd tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 316e0b9a84aScgd } while (--chars_in > 0); 317e0b9a84aScgd STORE(D,D0,D1,*out); 318e0b9a84aScgd } 319e0b9a84aScgd #endif /* LARGEDATA */ 320e0b9a84aScgd 321e0b9a84aScgd 322e0b9a84aScgd /* ===== (mostly) Standard DES Tables ==================== */ 323e0b9a84aScgd 324e0b9a84aScgd static unsigned char IP[] = { /* initial permutation */ 325e0b9a84aScgd 58, 50, 42, 34, 26, 18, 10, 2, 326e0b9a84aScgd 60, 52, 44, 36, 28, 20, 12, 4, 327e0b9a84aScgd 62, 54, 46, 38, 30, 22, 14, 6, 328e0b9a84aScgd 64, 56, 48, 40, 32, 24, 16, 8, 329e0b9a84aScgd 57, 49, 41, 33, 25, 17, 9, 1, 330e0b9a84aScgd 59, 51, 43, 35, 27, 19, 11, 3, 331e0b9a84aScgd 61, 53, 45, 37, 29, 21, 13, 5, 332e0b9a84aScgd 63, 55, 47, 39, 31, 23, 15, 7, 333e0b9a84aScgd }; 334e0b9a84aScgd 335e0b9a84aScgd /* The final permutation is the inverse of IP - no table is necessary */ 336e0b9a84aScgd 337e0b9a84aScgd static unsigned char ExpandTr[] = { /* expansion operation */ 338e0b9a84aScgd 32, 1, 2, 3, 4, 5, 339e0b9a84aScgd 4, 5, 6, 7, 8, 9, 340e0b9a84aScgd 8, 9, 10, 11, 12, 13, 341e0b9a84aScgd 12, 13, 14, 15, 16, 17, 342e0b9a84aScgd 16, 17, 18, 19, 20, 21, 343e0b9a84aScgd 20, 21, 22, 23, 24, 25, 344e0b9a84aScgd 24, 25, 26, 27, 28, 29, 345e0b9a84aScgd 28, 29, 30, 31, 32, 1, 346e0b9a84aScgd }; 347e0b9a84aScgd 348e0b9a84aScgd static unsigned char PC1[] = { /* permuted choice table 1 */ 349e0b9a84aScgd 57, 49, 41, 33, 25, 17, 9, 350e0b9a84aScgd 1, 58, 50, 42, 34, 26, 18, 351e0b9a84aScgd 10, 2, 59, 51, 43, 35, 27, 352e0b9a84aScgd 19, 11, 3, 60, 52, 44, 36, 353e0b9a84aScgd 354e0b9a84aScgd 63, 55, 47, 39, 31, 23, 15, 355e0b9a84aScgd 7, 62, 54, 46, 38, 30, 22, 356e0b9a84aScgd 14, 6, 61, 53, 45, 37, 29, 357e0b9a84aScgd 21, 13, 5, 28, 20, 12, 4, 358e0b9a84aScgd }; 359e0b9a84aScgd 360e0b9a84aScgd static unsigned char Rotates[] = { /* PC1 rotation schedule */ 361e0b9a84aScgd 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 362e0b9a84aScgd }; 363e0b9a84aScgd 364e0b9a84aScgd /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 365e0b9a84aScgd static unsigned char PC2[] = { /* permuted choice table 2 */ 366e0b9a84aScgd 9, 18, 14, 17, 11, 24, 1, 5, 367e0b9a84aScgd 22, 25, 3, 28, 15, 6, 21, 10, 368e0b9a84aScgd 35, 38, 23, 19, 12, 4, 26, 8, 369e0b9a84aScgd 43, 54, 16, 7, 27, 20, 13, 2, 370e0b9a84aScgd 371e0b9a84aScgd 0, 0, 41, 52, 31, 37, 47, 55, 372e0b9a84aScgd 0, 0, 30, 40, 51, 45, 33, 48, 373e0b9a84aScgd 0, 0, 44, 49, 39, 56, 34, 53, 374e0b9a84aScgd 0, 0, 46, 42, 50, 36, 29, 32, 375e0b9a84aScgd }; 376e0b9a84aScgd 377e0b9a84aScgd static unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 378e0b9a84aScgd /* S[1] */ 37931a2bdc6Smikel { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 380e0b9a84aScgd 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 381e0b9a84aScgd 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 38231a2bdc6Smikel 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, 383e0b9a84aScgd /* S[2] */ 38431a2bdc6Smikel { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 385e0b9a84aScgd 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 386e0b9a84aScgd 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 38731a2bdc6Smikel 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, 388e0b9a84aScgd /* S[3] */ 38931a2bdc6Smikel { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 390e0b9a84aScgd 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 391e0b9a84aScgd 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 39231a2bdc6Smikel 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, 393e0b9a84aScgd /* S[4] */ 39431a2bdc6Smikel { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 395e0b9a84aScgd 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 396e0b9a84aScgd 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 39731a2bdc6Smikel 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, 398e0b9a84aScgd /* S[5] */ 39931a2bdc6Smikel { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 400e0b9a84aScgd 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 401e0b9a84aScgd 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 40231a2bdc6Smikel 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, 403e0b9a84aScgd /* S[6] */ 40431a2bdc6Smikel { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 405e0b9a84aScgd 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 406e0b9a84aScgd 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 40731a2bdc6Smikel 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, 408e0b9a84aScgd /* S[7] */ 40931a2bdc6Smikel { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 410e0b9a84aScgd 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 411e0b9a84aScgd 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 41231a2bdc6Smikel 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, 413e0b9a84aScgd /* S[8] */ 41431a2bdc6Smikel { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 415e0b9a84aScgd 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 416e0b9a84aScgd 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 41731a2bdc6Smikel 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } 418e0b9a84aScgd }; 419e0b9a84aScgd 420e0b9a84aScgd static unsigned char P32Tr[] = { /* 32-bit permutation function */ 421e0b9a84aScgd 16, 7, 20, 21, 422e0b9a84aScgd 29, 12, 28, 17, 423e0b9a84aScgd 1, 15, 23, 26, 424e0b9a84aScgd 5, 18, 31, 10, 425e0b9a84aScgd 2, 8, 24, 14, 426e0b9a84aScgd 32, 27, 3, 9, 427e0b9a84aScgd 19, 13, 30, 6, 428e0b9a84aScgd 22, 11, 4, 25, 429e0b9a84aScgd }; 430e0b9a84aScgd 431e0b9a84aScgd static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 432e0b9a84aScgd 1, 2, 3, 4, 17, 18, 19, 20, 433e0b9a84aScgd 5, 6, 7, 8, 21, 22, 23, 24, 434e0b9a84aScgd 9, 10, 11, 12, 25, 26, 27, 28, 435e0b9a84aScgd 13, 14, 15, 16, 29, 30, 31, 32, 436e0b9a84aScgd 437e0b9a84aScgd 33, 34, 35, 36, 49, 50, 51, 52, 438e0b9a84aScgd 37, 38, 39, 40, 53, 54, 55, 56, 439e0b9a84aScgd 41, 42, 43, 44, 57, 58, 59, 60, 440e0b9a84aScgd 45, 46, 47, 48, 61, 62, 63, 64, 441e0b9a84aScgd }; 442e0b9a84aScgd 443e0b9a84aScgd static unsigned char itoa64[] = /* 0..63 => ascii-64 */ 444e0b9a84aScgd "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 445e0b9a84aScgd 446e0b9a84aScgd 447e0b9a84aScgd /* ===== Tables that are initialized at run time ==================== */ 448e0b9a84aScgd 449e0b9a84aScgd 450e0b9a84aScgd static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ 451e0b9a84aScgd 452e0b9a84aScgd /* Initial key schedule permutation */ 453e0b9a84aScgd static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 454e0b9a84aScgd 455e0b9a84aScgd /* Subsequent key schedule rotation permutations */ 456e0b9a84aScgd static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 457e0b9a84aScgd 458e0b9a84aScgd /* Initial permutation/expansion table */ 459e0b9a84aScgd static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 460e0b9a84aScgd 461e0b9a84aScgd /* Table that combines the S, P, and E operations. */ 462688980ebScgd static int32_t SPE[2][8][64]; 463e0b9a84aScgd 464e0b9a84aScgd /* compressed/interleaved => final permutation table */ 465e0b9a84aScgd static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 466e0b9a84aScgd 467e0b9a84aScgd 468e0b9a84aScgd /* ==================================== */ 469e0b9a84aScgd 470e0b9a84aScgd 471e0b9a84aScgd static C_block constdatablock; /* encryption constant */ 472e0b9a84aScgd static char cryptresult[1+4+4+11+1]; /* encrypted result */ 473e0b9a84aScgd 474e0b9a84aScgd /* 475e0b9a84aScgd * Return a pointer to static data consisting of the "setting" 476e0b9a84aScgd * followed by an encryption produced by the "key" and "setting". 477e0b9a84aScgd */ 478e0b9a84aScgd char * 479e0b9a84aScgd crypt(key, setting) 48006795b86Slukem const char *key; 48106795b86Slukem const char *setting; 482e0b9a84aScgd { 48306795b86Slukem char *encp; 48406795b86Slukem int32_t i; 48506795b86Slukem int t; 486688980ebScgd int32_t salt; 487e0b9a84aScgd int num_iter, salt_size; 488e0b9a84aScgd C_block keyblock, rsltblock; 489e0b9a84aScgd 490e0b9a84aScgd for (i = 0; i < 8; i++) { 491e0b9a84aScgd if ((t = 2*(unsigned char)(*key)) != 0) 492e0b9a84aScgd key++; 493e0b9a84aScgd keyblock.b[i] = t; 494e0b9a84aScgd } 495e0b9a84aScgd if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */ 496e0b9a84aScgd return (NULL); 497e0b9a84aScgd 498e0b9a84aScgd encp = &cryptresult[0]; 499e0b9a84aScgd switch (*setting) { 500e0b9a84aScgd case _PASSWORD_EFMT1: 501e0b9a84aScgd /* 502e0b9a84aScgd * Involve the rest of the password 8 characters at a time. 503e0b9a84aScgd */ 504e0b9a84aScgd while (*key) { 505e0b9a84aScgd if (des_cipher((char *)&keyblock, 506e0b9a84aScgd (char *)&keyblock, 0L, 1)) 507e0b9a84aScgd return (NULL); 508e0b9a84aScgd for (i = 0; i < 8; i++) { 509e0b9a84aScgd if ((t = 2*(unsigned char)(*key)) != 0) 510e0b9a84aScgd key++; 511e0b9a84aScgd keyblock.b[i] ^= t; 512e0b9a84aScgd } 513e0b9a84aScgd if (des_setkey((char *)keyblock.b)) 514e0b9a84aScgd return (NULL); 515e0b9a84aScgd } 516e0b9a84aScgd 517e0b9a84aScgd *encp++ = *setting++; 518e0b9a84aScgd 519e0b9a84aScgd /* get iteration count */ 520e0b9a84aScgd num_iter = 0; 521e0b9a84aScgd for (i = 4; --i >= 0; ) { 522e0b9a84aScgd if ((t = (unsigned char)setting[i]) == '\0') 523e0b9a84aScgd t = '.'; 524e0b9a84aScgd encp[i] = t; 525e0b9a84aScgd num_iter = (num_iter<<6) | a64toi[t]; 526e0b9a84aScgd } 527e0b9a84aScgd setting += 4; 528e0b9a84aScgd encp += 4; 529e0b9a84aScgd salt_size = 4; 530e0b9a84aScgd break; 531e0b9a84aScgd default: 532e0b9a84aScgd num_iter = 25; 533e0b9a84aScgd salt_size = 2; 534e0b9a84aScgd } 535e0b9a84aScgd 536e0b9a84aScgd salt = 0; 537e0b9a84aScgd for (i = salt_size; --i >= 0; ) { 538e0b9a84aScgd if ((t = (unsigned char)setting[i]) == '\0') 539e0b9a84aScgd t = '.'; 540e0b9a84aScgd encp[i] = t; 541e0b9a84aScgd salt = (salt<<6) | a64toi[t]; 542e0b9a84aScgd } 543e0b9a84aScgd encp += salt_size; 544e0b9a84aScgd if (des_cipher((char *)&constdatablock, (char *)&rsltblock, 545e0b9a84aScgd salt, num_iter)) 546e0b9a84aScgd return (NULL); 547e0b9a84aScgd 548e0b9a84aScgd /* 549e0b9a84aScgd * Encode the 64 cipher bits as 11 ascii characters. 550e0b9a84aScgd */ 551688980ebScgd i = ((int32_t)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | 552688980ebScgd rsltblock.b[2]; 553e0b9a84aScgd encp[3] = itoa64[i&0x3f]; i >>= 6; 554e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 555e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 556e0b9a84aScgd encp[0] = itoa64[i]; encp += 4; 557688980ebScgd i = ((int32_t)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | 558688980ebScgd rsltblock.b[5]; 559e0b9a84aScgd encp[3] = itoa64[i&0x3f]; i >>= 6; 560e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 561e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 562e0b9a84aScgd encp[0] = itoa64[i]; encp += 4; 563688980ebScgd i = ((int32_t)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 564e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 565e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 566e0b9a84aScgd encp[0] = itoa64[i]; 567e0b9a84aScgd 568e0b9a84aScgd encp[3] = 0; 569e0b9a84aScgd 570e0b9a84aScgd return (cryptresult); 571e0b9a84aScgd } 572e0b9a84aScgd 573e0b9a84aScgd 574e0b9a84aScgd /* 575e0b9a84aScgd * The Key Schedule, filled in by des_setkey() or setkey(). 576e0b9a84aScgd */ 577e0b9a84aScgd #define KS_SIZE 16 578e0b9a84aScgd static C_block KS[KS_SIZE]; 579e0b9a84aScgd 580e0b9a84aScgd /* 581e0b9a84aScgd * Set up the key schedule from the key. 582e0b9a84aScgd */ 58331a2bdc6Smikel int 584e0b9a84aScgd des_setkey(key) 58506795b86Slukem const char *key; 586e0b9a84aScgd { 58706795b86Slukem DCL_BLOCK(K, K0, K1); 58806795b86Slukem C_block *ptabp; 58906795b86Slukem int i; 590e0b9a84aScgd static int des_ready = 0; 591e0b9a84aScgd 592e0b9a84aScgd if (!des_ready) { 593e0b9a84aScgd init_des(); 594e0b9a84aScgd des_ready = 1; 595e0b9a84aScgd } 596e0b9a84aScgd 597e0b9a84aScgd PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT); 598e0b9a84aScgd key = (char *)&KS[0]; 599e0b9a84aScgd STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); 600e0b9a84aScgd for (i = 1; i < 16; i++) { 601e0b9a84aScgd key += sizeof(C_block); 602e0b9a84aScgd STORE(K,K0,K1,*(C_block *)key); 603e0b9a84aScgd ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 604e0b9a84aScgd PERM6464(K,K0,K1,(unsigned char *)key,ptabp); 605e0b9a84aScgd STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key); 606e0b9a84aScgd } 607e0b9a84aScgd return (0); 608e0b9a84aScgd } 609e0b9a84aScgd 610e0b9a84aScgd /* 611e0b9a84aScgd * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 612e0b9a84aScgd * iterations of DES, using the the given 24-bit salt and the pre-computed key 613e0b9a84aScgd * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 614e0b9a84aScgd * 615e0b9a84aScgd * NOTE: the performance of this routine is critically dependent on your 616e0b9a84aScgd * compiler and machine architecture. 617e0b9a84aScgd */ 61831a2bdc6Smikel int 619e0b9a84aScgd des_cipher(in, out, salt, num_iter) 620e0b9a84aScgd const char *in; 621e0b9a84aScgd char *out; 622e0b9a84aScgd long salt; 623e0b9a84aScgd int num_iter; 624e0b9a84aScgd { 625e0b9a84aScgd /* variables that we want in registers, most important first */ 626e0b9a84aScgd #if defined(pdp11) 6270b7831a3Sperry int j; 628e0b9a84aScgd #endif 6290b7831a3Sperry int32_t L0, L1, R0, R1, k; 6300b7831a3Sperry C_block *kp; 6310b7831a3Sperry int ks_inc, loop_count; 632e0b9a84aScgd C_block B; 633e0b9a84aScgd 634e0b9a84aScgd L0 = salt; 635e0b9a84aScgd TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ 636e0b9a84aScgd 637e0b9a84aScgd #if defined(vax) || defined(pdp11) 638e0b9a84aScgd salt = ~salt; /* "x &~ y" is faster than "x & y". */ 639e0b9a84aScgd #define SALT (~salt) 640e0b9a84aScgd #else 641e0b9a84aScgd #define SALT salt 642e0b9a84aScgd #endif 643e0b9a84aScgd 644e0b9a84aScgd #if defined(MUST_ALIGN) 645e0b9a84aScgd B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 646e0b9a84aScgd B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 647e0b9a84aScgd LOAD(L,L0,L1,B); 648e0b9a84aScgd #else 649e0b9a84aScgd LOAD(L,L0,L1,*(C_block *)in); 650e0b9a84aScgd #endif 651e0b9a84aScgd LOADREG(R,R0,R1,L,L0,L1); 652e0b9a84aScgd L0 &= 0x55555555L; 653e0b9a84aScgd L1 &= 0x55555555L; 654e0b9a84aScgd L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ 655e0b9a84aScgd R0 &= 0xaaaaaaaaL; 656e0b9a84aScgd R1 = (R1 >> 1) & 0x55555555L; 657e0b9a84aScgd L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 658e0b9a84aScgd STORE(L,L0,L1,B); 659e0b9a84aScgd PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 660e0b9a84aScgd PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 661e0b9a84aScgd 662e0b9a84aScgd if (num_iter >= 0) 663e0b9a84aScgd { /* encryption */ 664e0b9a84aScgd kp = &KS[0]; 665e0b9a84aScgd ks_inc = sizeof(*kp); 666e0b9a84aScgd } 667e0b9a84aScgd else 668e0b9a84aScgd { /* decryption */ 6694902ac3dScgd return (1); /* always fail */ 670e0b9a84aScgd } 671e0b9a84aScgd 672e0b9a84aScgd while (--num_iter >= 0) { 673e0b9a84aScgd loop_count = 8; 674e0b9a84aScgd do { 675e0b9a84aScgd 676688980ebScgd #define SPTAB(t, i) \ 677688980ebScgd (*(int32_t *)((unsigned char *)t + i*(sizeof(int32_t)/4))) 678e0b9a84aScgd #if defined(gould) 679e0b9a84aScgd /* use this if B.b[i] is evaluated just once ... */ 680e0b9a84aScgd #define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); 681e0b9a84aScgd #else 682e0b9a84aScgd #if defined(pdp11) 683e0b9a84aScgd /* use this if your "long" int indexing is slow */ 684e0b9a84aScgd #define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); 685e0b9a84aScgd #else 68695eeab3bSmikel /* use this if "k" is allocated to a register ... */ 687e0b9a84aScgd #define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); 688e0b9a84aScgd #endif 689e0b9a84aScgd #endif 690e0b9a84aScgd 691e0b9a84aScgd #define CRUNCH(p0, p1, q0, q1) \ 692e0b9a84aScgd k = (q0 ^ q1) & SALT; \ 693e0b9a84aScgd B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ 694e0b9a84aScgd B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ 695e0b9a84aScgd kp = (C_block *)((char *)kp+ks_inc); \ 696e0b9a84aScgd \ 697e0b9a84aScgd DOXOR(p0, p1, 0); \ 698e0b9a84aScgd DOXOR(p0, p1, 1); \ 699e0b9a84aScgd DOXOR(p0, p1, 2); \ 700e0b9a84aScgd DOXOR(p0, p1, 3); \ 701e0b9a84aScgd DOXOR(p0, p1, 4); \ 702e0b9a84aScgd DOXOR(p0, p1, 5); \ 703e0b9a84aScgd DOXOR(p0, p1, 6); \ 704e0b9a84aScgd DOXOR(p0, p1, 7); 705e0b9a84aScgd 706e0b9a84aScgd CRUNCH(L0, L1, R0, R1); 707e0b9a84aScgd CRUNCH(R0, R1, L0, L1); 708e0b9a84aScgd } while (--loop_count != 0); 709e0b9a84aScgd kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 710e0b9a84aScgd 711e0b9a84aScgd 712e0b9a84aScgd /* swap L and R */ 713e0b9a84aScgd L0 ^= R0; L1 ^= R1; 714e0b9a84aScgd R0 ^= L0; R1 ^= L1; 715e0b9a84aScgd L0 ^= R0; L1 ^= R1; 716e0b9a84aScgd } 717e0b9a84aScgd 718e0b9a84aScgd /* store the encrypted (or decrypted) result */ 719e0b9a84aScgd L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); 720e0b9a84aScgd L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); 721e0b9a84aScgd STORE(L,L0,L1,B); 722e0b9a84aScgd PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 723e0b9a84aScgd #if defined(MUST_ALIGN) 724e0b9a84aScgd STORE(L,L0,L1,B); 725e0b9a84aScgd out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 726e0b9a84aScgd out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 727e0b9a84aScgd #else 728e0b9a84aScgd STORE(L,L0,L1,*(C_block *)out); 729e0b9a84aScgd #endif 730e0b9a84aScgd return (0); 731e0b9a84aScgd } 732e0b9a84aScgd 733e0b9a84aScgd 734e0b9a84aScgd /* 735e0b9a84aScgd * Initialize various tables. This need only be done once. It could even be 736e0b9a84aScgd * done at compile time, if the compiler were capable of that sort of thing. 737e0b9a84aScgd */ 738e0b9a84aScgd STATIC 739e0b9a84aScgd init_des() 740e0b9a84aScgd { 74106795b86Slukem int i, j; 74206795b86Slukem int32_t k; 74306795b86Slukem int tableno; 744e0b9a84aScgd static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 745e0b9a84aScgd 746e0b9a84aScgd /* 747e0b9a84aScgd * table that converts chars "./0-9A-Za-z"to integers 0-63. 748e0b9a84aScgd */ 749e0b9a84aScgd for (i = 0; i < 64; i++) 750e0b9a84aScgd a64toi[itoa64[i]] = i; 751e0b9a84aScgd 752e0b9a84aScgd /* 753e0b9a84aScgd * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 754e0b9a84aScgd */ 755e0b9a84aScgd for (i = 0; i < 64; i++) 756e0b9a84aScgd perm[i] = 0; 757e0b9a84aScgd for (i = 0; i < 64; i++) { 758e0b9a84aScgd if ((k = PC2[i]) == 0) 759e0b9a84aScgd continue; 760e0b9a84aScgd k += Rotates[0]-1; 761e0b9a84aScgd if ((k%28) < Rotates[0]) k -= 28; 762e0b9a84aScgd k = PC1[k]; 763e0b9a84aScgd if (k > 0) { 764e0b9a84aScgd k--; 765e0b9a84aScgd k = (k|07) - (k&07); 766e0b9a84aScgd k++; 767e0b9a84aScgd } 768e0b9a84aScgd perm[i] = k; 769e0b9a84aScgd } 770e0b9a84aScgd #ifdef DEBUG 771e0b9a84aScgd prtab("pc1tab", perm, 8); 772e0b9a84aScgd #endif 773e0b9a84aScgd init_perm(PC1ROT, perm, 8, 8); 774e0b9a84aScgd 775e0b9a84aScgd /* 776e0b9a84aScgd * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 777e0b9a84aScgd */ 778e0b9a84aScgd for (j = 0; j < 2; j++) { 779e0b9a84aScgd unsigned char pc2inv[64]; 780e0b9a84aScgd for (i = 0; i < 64; i++) 781e0b9a84aScgd perm[i] = pc2inv[i] = 0; 782e0b9a84aScgd for (i = 0; i < 64; i++) { 783e0b9a84aScgd if ((k = PC2[i]) == 0) 784e0b9a84aScgd continue; 785e0b9a84aScgd pc2inv[k-1] = i+1; 786e0b9a84aScgd } 787e0b9a84aScgd for (i = 0; i < 64; i++) { 788e0b9a84aScgd if ((k = PC2[i]) == 0) 789e0b9a84aScgd continue; 790e0b9a84aScgd k += j; 791e0b9a84aScgd if ((k%28) <= j) k -= 28; 792e0b9a84aScgd perm[i] = pc2inv[k]; 793e0b9a84aScgd } 794e0b9a84aScgd #ifdef DEBUG 795e0b9a84aScgd prtab("pc2tab", perm, 8); 796e0b9a84aScgd #endif 797e0b9a84aScgd init_perm(PC2ROT[j], perm, 8, 8); 798e0b9a84aScgd } 799e0b9a84aScgd 800e0b9a84aScgd /* 801e0b9a84aScgd * Bit reverse, then initial permutation, then expansion. 802e0b9a84aScgd */ 803e0b9a84aScgd for (i = 0; i < 8; i++) { 804e0b9a84aScgd for (j = 0; j < 8; j++) { 805e0b9a84aScgd k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 806e0b9a84aScgd if (k > 32) 807e0b9a84aScgd k -= 32; 808e0b9a84aScgd else if (k > 0) 809e0b9a84aScgd k--; 810e0b9a84aScgd if (k > 0) { 811e0b9a84aScgd k--; 812e0b9a84aScgd k = (k|07) - (k&07); 813e0b9a84aScgd k++; 814e0b9a84aScgd } 815e0b9a84aScgd perm[i*8+j] = k; 816e0b9a84aScgd } 817e0b9a84aScgd } 818e0b9a84aScgd #ifdef DEBUG 819e0b9a84aScgd prtab("ietab", perm, 8); 820e0b9a84aScgd #endif 821e0b9a84aScgd init_perm(IE3264, perm, 4, 8); 822e0b9a84aScgd 823e0b9a84aScgd /* 824e0b9a84aScgd * Compression, then final permutation, then bit reverse. 825e0b9a84aScgd */ 826e0b9a84aScgd for (i = 0; i < 64; i++) { 827e0b9a84aScgd k = IP[CIFP[i]-1]; 828e0b9a84aScgd if (k > 0) { 829e0b9a84aScgd k--; 830e0b9a84aScgd k = (k|07) - (k&07); 831e0b9a84aScgd k++; 832e0b9a84aScgd } 833e0b9a84aScgd perm[k-1] = i+1; 834e0b9a84aScgd } 835e0b9a84aScgd #ifdef DEBUG 836e0b9a84aScgd prtab("cftab", perm, 8); 837e0b9a84aScgd #endif 838e0b9a84aScgd init_perm(CF6464, perm, 8, 8); 839e0b9a84aScgd 840e0b9a84aScgd /* 841e0b9a84aScgd * SPE table 842e0b9a84aScgd */ 843e0b9a84aScgd for (i = 0; i < 48; i++) 844e0b9a84aScgd perm[i] = P32Tr[ExpandTr[i]-1]; 845e0b9a84aScgd for (tableno = 0; tableno < 8; tableno++) { 846e0b9a84aScgd for (j = 0; j < 64; j++) { 847e0b9a84aScgd k = (((j >> 0) &01) << 5)| 848e0b9a84aScgd (((j >> 1) &01) << 3)| 849e0b9a84aScgd (((j >> 2) &01) << 2)| 850e0b9a84aScgd (((j >> 3) &01) << 1)| 851e0b9a84aScgd (((j >> 4) &01) << 0)| 852e0b9a84aScgd (((j >> 5) &01) << 4); 853e0b9a84aScgd k = S[tableno][k]; 854e0b9a84aScgd k = (((k >> 3)&01) << 0)| 855e0b9a84aScgd (((k >> 2)&01) << 1)| 856e0b9a84aScgd (((k >> 1)&01) << 2)| 857e0b9a84aScgd (((k >> 0)&01) << 3); 858e0b9a84aScgd for (i = 0; i < 32; i++) 859e0b9a84aScgd tmp32[i] = 0; 860e0b9a84aScgd for (i = 0; i < 4; i++) 861e0b9a84aScgd tmp32[4 * tableno + i] = (k >> i) & 01; 862e0b9a84aScgd k = 0; 863e0b9a84aScgd for (i = 24; --i >= 0; ) 864e0b9a84aScgd k = (k<<1) | tmp32[perm[i]-1]; 865e0b9a84aScgd TO_SIX_BIT(SPE[0][tableno][j], k); 866e0b9a84aScgd k = 0; 867e0b9a84aScgd for (i = 24; --i >= 0; ) 868e0b9a84aScgd k = (k<<1) | tmp32[perm[i+24]-1]; 869e0b9a84aScgd TO_SIX_BIT(SPE[1][tableno][j], k); 870e0b9a84aScgd } 871e0b9a84aScgd } 872e0b9a84aScgd } 873e0b9a84aScgd 874e0b9a84aScgd /* 875e0b9a84aScgd * Initialize "perm" to represent transformation "p", which rearranges 876e0b9a84aScgd * (perhaps with expansion and/or contraction) one packed array of bits 877e0b9a84aScgd * (of size "chars_in" characters) into another array (of size "chars_out" 878e0b9a84aScgd * characters). 879e0b9a84aScgd * 880e0b9a84aScgd * "perm" must be all-zeroes on entry to this routine. 881e0b9a84aScgd */ 882e0b9a84aScgd STATIC 883e0b9a84aScgd init_perm(perm, p, chars_in, chars_out) 884e0b9a84aScgd C_block perm[64/CHUNKBITS][1<<CHUNKBITS]; 885e0b9a84aScgd unsigned char p[64]; 886e0b9a84aScgd int chars_in, chars_out; 887e0b9a84aScgd { 88806795b86Slukem int i, j, k, l; 889e0b9a84aScgd 890e0b9a84aScgd for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 891e0b9a84aScgd l = p[k] - 1; /* where this bit comes from */ 892e0b9a84aScgd if (l < 0) 893e0b9a84aScgd continue; /* output bit is always 0 */ 894e0b9a84aScgd i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 895e0b9a84aScgd l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 896e0b9a84aScgd for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 897e0b9a84aScgd if ((j & l) != 0) 898e0b9a84aScgd perm[i][j].b[k>>3] |= 1<<(k&07); 899e0b9a84aScgd } 900e0b9a84aScgd } 901e0b9a84aScgd } 902e0b9a84aScgd 903e0b9a84aScgd /* 904e0b9a84aScgd * "setkey" routine (for backwards compatibility) 905e0b9a84aScgd */ 90631a2bdc6Smikel int 907e0b9a84aScgd setkey(key) 90806795b86Slukem const char *key; 909e0b9a84aScgd { 91006795b86Slukem int i, j, k; 911e0b9a84aScgd C_block keyblock; 912e0b9a84aScgd 913e0b9a84aScgd for (i = 0; i < 8; i++) { 914e0b9a84aScgd k = 0; 915e0b9a84aScgd for (j = 0; j < 8; j++) { 916e0b9a84aScgd k <<= 1; 917e0b9a84aScgd k |= (unsigned char)*key++; 918e0b9a84aScgd } 919e0b9a84aScgd keyblock.b[i] = k; 920e0b9a84aScgd } 921e0b9a84aScgd return (des_setkey((char *)keyblock.b)); 922e0b9a84aScgd } 923e0b9a84aScgd 924e0b9a84aScgd /* 925e0b9a84aScgd * "encrypt" routine (for backwards compatibility) 926e0b9a84aScgd */ 92731a2bdc6Smikel int 928e0b9a84aScgd encrypt(block, flag) 92906795b86Slukem char *block; 930e0b9a84aScgd int flag; 931e0b9a84aScgd { 93206795b86Slukem int i, j, k; 933e0b9a84aScgd C_block cblock; 934e0b9a84aScgd 935e0b9a84aScgd for (i = 0; i < 8; i++) { 936e0b9a84aScgd k = 0; 937e0b9a84aScgd for (j = 0; j < 8; j++) { 938e0b9a84aScgd k <<= 1; 939e0b9a84aScgd k |= (unsigned char)*block++; 940e0b9a84aScgd } 941e0b9a84aScgd cblock.b[i] = k; 942e0b9a84aScgd } 943e0b9a84aScgd if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) 944e0b9a84aScgd return (1); 945e0b9a84aScgd for (i = 7; i >= 0; i--) { 946e0b9a84aScgd k = cblock.b[i]; 947e0b9a84aScgd for (j = 7; j >= 0; j--) { 948e0b9a84aScgd *--block = k&01; 949e0b9a84aScgd k >>= 1; 950e0b9a84aScgd } 951e0b9a84aScgd } 952e0b9a84aScgd return (0); 953e0b9a84aScgd } 954e0b9a84aScgd 955e0b9a84aScgd #ifdef DEBUG 956e0b9a84aScgd STATIC 957e0b9a84aScgd prtab(s, t, num_rows) 958e0b9a84aScgd char *s; 959e0b9a84aScgd unsigned char *t; 960e0b9a84aScgd int num_rows; 961e0b9a84aScgd { 96206795b86Slukem int i, j; 963e0b9a84aScgd 964e0b9a84aScgd (void)printf("%s:\n", s); 965e0b9a84aScgd for (i = 0; i < num_rows; i++) { 966e0b9a84aScgd for (j = 0; j < 8; j++) { 967e0b9a84aScgd (void)printf("%3d", t[i*8+j]); 968e0b9a84aScgd } 969e0b9a84aScgd (void)printf("\n"); 970e0b9a84aScgd } 971e0b9a84aScgd (void)printf("\n"); 972e0b9a84aScgd } 973e0b9a84aScgd #endif 974