1*4d92dbe9Sriastradh /* $NetBSD: crypt.c,v 1.41 2024/07/23 22:37:11 riastradh 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. 18eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors 19e0b9a84aScgd * may be used to endorse or promote products derived from this software 20e0b9a84aScgd * without specific prior written permission. 21e0b9a84aScgd * 22e0b9a84aScgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23e0b9a84aScgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24e0b9a84aScgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25e0b9a84aScgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26e0b9a84aScgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27e0b9a84aScgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28e0b9a84aScgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29e0b9a84aScgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30e0b9a84aScgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31e0b9a84aScgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32e0b9a84aScgd * SUCH DAMAGE. 33e0b9a84aScgd */ 34e0b9a84aScgd 3506795b86Slukem #include <sys/cdefs.h> 3606795b86Slukem #if !defined(lint) 374902ac3dScgd #if 0 384902ac3dScgd static char sccsid[] = "@(#)crypt.c 8.1.1.1 (Berkeley) 8/18/93"; 3906795b86Slukem #else 40*4d92dbe9Sriastradh __RCSID("$NetBSD: crypt.c,v 1.41 2024/07/23 22:37:11 riastradh Exp $"); 414902ac3dScgd #endif 4206795b86Slukem #endif /* not lint */ 43e0b9a84aScgd 44e0b9a84aScgd #include <limits.h> 45e0b9a84aScgd #include <pwd.h> 4656545abaSkleink #include <stdlib.h> 47c7ab523eSjhigh #include <string.h> /* for strcmp */ 4831a2bdc6Smikel #include <unistd.h> 4955ac93d3Shubertf #if defined(DEBUG) || defined(MAIN) || defined(UNIT_TEST) 50a0d45c26Schristos #include <stdio.h> 51a0d45c26Schristos #endif 52e0b9a84aScgd 533a0c68edSsjg #include "crypt.h" 543a0c68edSsjg 55e0b9a84aScgd /* 56e0b9a84aScgd * UNIX password, and DES, encryption. 57e0b9a84aScgd * By Tom Truscott, trt@rti.rti.org, 58e0b9a84aScgd * from algorithms by Robert W. Baldwin and James Gillogly. 59e0b9a84aScgd * 60e0b9a84aScgd * References: 61e0b9a84aScgd * "Mathematical Cryptology for Computer Scientists and Mathematicians," 62e0b9a84aScgd * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. 63e0b9a84aScgd * 64e0b9a84aScgd * "Password Security: A Case History," R. Morris and Ken Thompson, 65e0b9a84aScgd * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. 66e0b9a84aScgd * 67e0b9a84aScgd * "DES will be Totally Insecure within Ten Years," M.E. Hellman, 68e0b9a84aScgd * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. 69e0b9a84aScgd */ 70e0b9a84aScgd 71e0b9a84aScgd /* ===== Configuration ==================== */ 72e0b9a84aScgd 73e0b9a84aScgd /* 74e0b9a84aScgd * define "MUST_ALIGN" if your compiler cannot load/store 75e0b9a84aScgd * long integers at arbitrary (e.g. odd) memory locations. 76e0b9a84aScgd * (Either that or never pass unaligned addresses to des_cipher!) 77e0b9a84aScgd */ 7859695352Smatt #if !defined(__vax__) && !defined(__i386__) 79e0b9a84aScgd #define MUST_ALIGN 80e0b9a84aScgd #endif 81e0b9a84aScgd 82e0b9a84aScgd #ifdef CHAR_BITS 83e0b9a84aScgd #if CHAR_BITS != 8 84e0b9a84aScgd #error C_block structure assumes 8 bit characters 85e0b9a84aScgd #endif 86e0b9a84aScgd #endif 87e0b9a84aScgd 88e0b9a84aScgd /* 89e0b9a84aScgd * define "B64" to be the declaration for a 64 bit integer. 90e0b9a84aScgd * XXX this feature is currently unused, see "endian" comment below. 91e0b9a84aScgd */ 92e0b9a84aScgd #if defined(cray) 93e0b9a84aScgd #define B64 long 94e0b9a84aScgd #endif 95e0b9a84aScgd #if defined(convex) 96e0b9a84aScgd #define B64 long long 97e0b9a84aScgd #endif 98e0b9a84aScgd 99e0b9a84aScgd /* 100e0b9a84aScgd * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes 101e0b9a84aScgd * of lookup tables. This speeds up des_setkey() and des_cipher(), but has 102e0b9a84aScgd * little effect on crypt(). 103e0b9a84aScgd */ 104e0b9a84aScgd #if defined(notdef) 105e0b9a84aScgd #define LARGEDATA 106e0b9a84aScgd #endif 107e0b9a84aScgd 10831a2bdc6Smikel /* compile with "-DSTATIC=void" when profiling */ 109e0b9a84aScgd #ifndef STATIC 11031a2bdc6Smikel #define STATIC static void 111e0b9a84aScgd #endif 112e0b9a84aScgd 113e0b9a84aScgd /* ==================================== */ 114e0b9a84aScgd 115e0b9a84aScgd /* 116e0b9a84aScgd * Cipher-block representation (Bob Baldwin): 117e0b9a84aScgd * 118e0b9a84aScgd * DES operates on groups of 64 bits, numbered 1..64 (sigh). One 119e0b9a84aScgd * representation is to store one bit per byte in an array of bytes. Bit N of 120e0b9a84aScgd * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. 121e0b9a84aScgd * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the 122e0b9a84aScgd * first byte, 9..16 in the second, and so on. The DES spec apparently has 123e0b9a84aScgd * bit 1 in the MSB of the first byte, but that is particularly noxious so we 124e0b9a84aScgd * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is 125e0b9a84aScgd * the MSB of the first byte. Specifically, the 64-bit input data and key are 126e0b9a84aScgd * converted to LSB format, and the output 64-bit block is converted back into 127e0b9a84aScgd * MSB format. 128e0b9a84aScgd * 129e0b9a84aScgd * DES operates internally on groups of 32 bits which are expanded to 48 bits 130e0b9a84aScgd * by permutation E and shrunk back to 32 bits by the S boxes. To speed up 131e0b9a84aScgd * the computation, the expansion is applied only once, the expanded 132e0b9a84aScgd * representation is maintained during the encryption, and a compression 133e0b9a84aScgd * permutation is applied only at the end. To speed up the S-box lookups, 134e0b9a84aScgd * the 48 bits are maintained as eight 6 bit groups, one per byte, which 135e0b9a84aScgd * directly feed the eight S-boxes. Within each byte, the 6 bits are the 136e0b9a84aScgd * most significant ones. The low two bits of each byte are zero. (Thus, 137e0b9a84aScgd * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the 138e0b9a84aScgd * first byte in the eight byte representation, bit 2 of the 48 bit value is 139e0b9a84aScgd * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is 140e0b9a84aScgd * used, in which the output is the 64 bit result of an S-box lookup which 141e0b9a84aScgd * has been permuted by P and expanded by E, and is ready for use in the next 142e0b9a84aScgd * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this 143e0b9a84aScgd * lookup. Since each byte in the 48 bit path is a multiple of four, indexed 144e0b9a84aScgd * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and 145e0b9a84aScgd * "salt" are also converted to this 8*(6+2) format. The SPE table size is 146e0b9a84aScgd * 8*64*8 = 4K bytes. 147e0b9a84aScgd * 148e0b9a84aScgd * To speed up bit-parallel operations (such as XOR), the 8 byte 149e0b9a84aScgd * representation is "union"ed with 32 bit values "i0" and "i1", and, on 150e0b9a84aScgd * machines which support it, a 64 bit value "b64". This data structure, 151e0b9a84aScgd * "C_block", has two problems. First, alignment restrictions must be 152e0b9a84aScgd * honored. Second, the byte-order (e.g. little-endian or big-endian) of 153e0b9a84aScgd * the architecture becomes visible. 154e0b9a84aScgd * 155e0b9a84aScgd * The byte-order problem is unfortunate, since on the one hand it is good 156e0b9a84aScgd * to have a machine-independent C_block representation (bits 1..8 in the 157e0b9a84aScgd * first byte, etc.), and on the other hand it is good for the LSB of the 158e0b9a84aScgd * first byte to be the LSB of i0. We cannot have both these things, so we 159e0b9a84aScgd * currently use the "little-endian" representation and avoid any multi-byte 160e0b9a84aScgd * operations that depend on byte order. This largely precludes use of the 161e0b9a84aScgd * 64-bit datatype since the relative order of i0 and i1 are unknown. It 162e0b9a84aScgd * also inhibits grouping the SPE table to look up 12 bits at a time. (The 163e0b9a84aScgd * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 164e0b9a84aScgd * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the 165e0b9a84aScgd * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup 166e0b9a84aScgd * requires a 128 kilobyte table, so perhaps this is not a big loss. 167e0b9a84aScgd * 168e0b9a84aScgd * Permutation representation (Jim Gillogly): 169e0b9a84aScgd * 170e0b9a84aScgd * A transformation is defined by its effect on each of the 8 bytes of the 171e0b9a84aScgd * 64-bit input. For each byte we give a 64-bit output that has the bits in 172e0b9a84aScgd * the input distributed appropriately. The transformation is then the OR 173e0b9a84aScgd * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for 174e0b9a84aScgd * each transformation. Unless LARGEDATA is defined, however, a more compact 175e0b9a84aScgd * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. 176e0b9a84aScgd * The smaller table uses 16*16*8 = 2K bytes for each transformation. This 177e0b9a84aScgd * is slower but tolerable, particularly for password encryption in which 178e0b9a84aScgd * the SPE transformation is iterated many times. The small tables total 9K 179e0b9a84aScgd * bytes, the large tables total 72K bytes. 180e0b9a84aScgd * 181e0b9a84aScgd * The transformations used are: 182e0b9a84aScgd * IE3264: MSB->LSB conversion, initial permutation, and expansion. 183e0b9a84aScgd * This is done by collecting the 32 even-numbered bits and applying 184e0b9a84aScgd * a 32->64 bit transformation, and then collecting the 32 odd-numbered 185e0b9a84aScgd * bits and applying the same transformation. Since there are only 186e0b9a84aScgd * 32 input bits, the IE3264 transformation table is half the size of 187e0b9a84aScgd * the usual table. 188e0b9a84aScgd * CF6464: Compression, final permutation, and LSB->MSB conversion. 189e0b9a84aScgd * This is done by two trivial 48->32 bit compressions to obtain 190e0b9a84aScgd * a 64-bit block (the bit numbering is given in the "CIFP" table) 191e0b9a84aScgd * followed by a 64->64 bit "cleanup" transformation. (It would 192e0b9a84aScgd * be possible to group the bits in the 64-bit block so that 2 193e0b9a84aScgd * identical 32->32 bit transformations could be used instead, 194e0b9a84aScgd * saving a factor of 4 in space and possibly 2 in time, but 195e0b9a84aScgd * byte-ordering and other complications rear their ugly head. 196e0b9a84aScgd * Similar opportunities/problems arise in the key schedule 197e0b9a84aScgd * transforms.) 198e0b9a84aScgd * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. 199e0b9a84aScgd * This admittedly baroque 64->64 bit transformation is used to 200e0b9a84aScgd * produce the first code (in 8*(6+2) format) of the key schedule. 201e0b9a84aScgd * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. 202e0b9a84aScgd * It would be possible to define 15 more transformations, each 203e0b9a84aScgd * with a different rotation, to generate the entire key schedule. 204e0b9a84aScgd * To save space, however, we instead permute each code into the 205e0b9a84aScgd * next by using a transformation that "undoes" the PC2 permutation, 206e0b9a84aScgd * rotates the code, and then applies PC2. Unfortunately, PC2 207e0b9a84aScgd * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not 208e0b9a84aScgd * invertible. We get around that problem by using a modified PC2 209e0b9a84aScgd * which retains the 8 otherwise-lost bits in the unused low-order 210e0b9a84aScgd * bits of each byte. The low-order bits are cleared when the 211e0b9a84aScgd * codes are stored into the key schedule. 212e0b9a84aScgd * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. 213e0b9a84aScgd * This is faster than applying PC2ROT[0] twice, 214e0b9a84aScgd * 215e0b9a84aScgd * The Bell Labs "salt" (Bob Baldwin): 216e0b9a84aScgd * 217e0b9a84aScgd * The salting is a simple permutation applied to the 48-bit result of E. 218e0b9a84aScgd * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and 219e0b9a84aScgd * i+24 of the result are swapped. The salt is thus a 24 bit number, with 220e0b9a84aScgd * 16777216 possible values. (The original salt was 12 bits and could not 221e0b9a84aScgd * swap bits 13..24 with 36..48.) 222e0b9a84aScgd * 223e0b9a84aScgd * It is possible, but ugly, to warp the SPE table to account for the salt 224e0b9a84aScgd * permutation. Fortunately, the conditional bit swapping requires only 225e0b9a84aScgd * about four machine instructions and can be done on-the-fly with about an 226e0b9a84aScgd * 8% performance penalty. 227e0b9a84aScgd */ 228e0b9a84aScgd 229e0b9a84aScgd typedef union { 230e0b9a84aScgd unsigned char b[8]; 231e0b9a84aScgd struct { 232688980ebScgd int32_t i0; 233688980ebScgd int32_t i1; 234e0b9a84aScgd } b32; 235e0b9a84aScgd #if defined(B64) 236e0b9a84aScgd B64 b64; 237e0b9a84aScgd #endif 238e0b9a84aScgd } C_block; 239e0b9a84aScgd 240e0b9a84aScgd /* 241e0b9a84aScgd * Convert twenty-four-bit long in host-order 242e0b9a84aScgd * to six bits (and 2 low-order zeroes) per char little-endian format. 243e0b9a84aScgd */ 244e0b9a84aScgd #define TO_SIX_BIT(rslt, src) { \ 245e0b9a84aScgd C_block cvt; \ 246e0b9a84aScgd cvt.b[0] = src; src >>= 6; \ 247e0b9a84aScgd cvt.b[1] = src; src >>= 6; \ 248e0b9a84aScgd cvt.b[2] = src; src >>= 6; \ 249e0b9a84aScgd cvt.b[3] = src; \ 250e0b9a84aScgd rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ 251e0b9a84aScgd } 252e0b9a84aScgd 253e0b9a84aScgd /* 254e0b9a84aScgd * These macros may someday permit efficient use of 64-bit integers. 255e0b9a84aScgd */ 256e0b9a84aScgd #define ZERO(d,d0,d1) d0 = 0, d1 = 0 257e0b9a84aScgd #define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 258e0b9a84aScgd #define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 259e0b9a84aScgd #define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 260e0b9a84aScgd #define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 261688980ebScgd #define DCL_BLOCK(d,d0,d1) int32_t d0, d1 262e0b9a84aScgd 263e0b9a84aScgd #if defined(LARGEDATA) 264e0b9a84aScgd /* Waste memory like crazy. Also, do permutations in line */ 265e0b9a84aScgd #define LGCHUNKBITS 3 266e0b9a84aScgd #define CHUNKBITS (1<<LGCHUNKBITS) 267e0b9a84aScgd #define PERM6464(d,d0,d1,cpp,p) \ 268e0b9a84aScgd LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 269e0b9a84aScgd OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 270e0b9a84aScgd OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 271e0b9a84aScgd OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \ 272e0b9a84aScgd OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \ 273e0b9a84aScgd OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \ 274e0b9a84aScgd OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \ 275e0b9a84aScgd OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]); 276e0b9a84aScgd #define PERM3264(d,d0,d1,cpp,p) \ 277e0b9a84aScgd LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \ 278e0b9a84aScgd OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \ 279e0b9a84aScgd OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \ 280e0b9a84aScgd OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); 281e0b9a84aScgd #else 282e0b9a84aScgd /* "small data" */ 283e0b9a84aScgd #define LGCHUNKBITS 2 284e0b9a84aScgd #define CHUNKBITS (1<<LGCHUNKBITS) 285e0b9a84aScgd #define PERM6464(d,d0,d1,cpp,p) \ 286e0b9a84aScgd { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); } 287e0b9a84aScgd #define PERM3264(d,d0,d1,cpp,p) \ 288e0b9a84aScgd { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); } 289cd0a22a4Smikel #endif /* LARGEDATA */ 29006795b86Slukem 291b34e9d9fSperry STATIC init_des(void); 292b34e9d9fSperry STATIC init_perm(C_block [64/CHUNKBITS][1<<CHUNKBITS], 293b34e9d9fSperry const unsigned char [64], int, int); 294cd0a22a4Smikel #ifndef LARGEDATA 295b34e9d9fSperry STATIC permute(const unsigned char *, C_block *, C_block *, int); 296cd0a22a4Smikel #endif 29706795b86Slukem #ifdef DEBUG 298b34e9d9fSperry STATIC prtab(const char *, unsigned char *, int); 29906795b86Slukem #endif 30006795b86Slukem 30106795b86Slukem 302cd0a22a4Smikel #ifndef LARGEDATA 303e0b9a84aScgd STATIC 30459153410Sperry permute(const unsigned char *cp, C_block *out, C_block *p, int chars_in) 305e0b9a84aScgd { 30606795b86Slukem DCL_BLOCK(D,D0,D1); 30706795b86Slukem C_block *tp; 30806795b86Slukem int t; 309e0b9a84aScgd 310e0b9a84aScgd ZERO(D,D0,D1); 311e0b9a84aScgd do { 312e0b9a84aScgd t = *cp++; 313e0b9a84aScgd tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 314e0b9a84aScgd tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS); 315e0b9a84aScgd } while (--chars_in > 0); 316e0b9a84aScgd STORE(D,D0,D1,*out); 317e0b9a84aScgd } 318e0b9a84aScgd #endif /* LARGEDATA */ 319e0b9a84aScgd 320e0b9a84aScgd 321e0b9a84aScgd /* ===== (mostly) Standard DES Tables ==================== */ 322e0b9a84aScgd 323d7d75e06Sjdolecek static const unsigned char IP[] = { /* initial permutation */ 324e0b9a84aScgd 58, 50, 42, 34, 26, 18, 10, 2, 325e0b9a84aScgd 60, 52, 44, 36, 28, 20, 12, 4, 326e0b9a84aScgd 62, 54, 46, 38, 30, 22, 14, 6, 327e0b9a84aScgd 64, 56, 48, 40, 32, 24, 16, 8, 328e0b9a84aScgd 57, 49, 41, 33, 25, 17, 9, 1, 329e0b9a84aScgd 59, 51, 43, 35, 27, 19, 11, 3, 330e0b9a84aScgd 61, 53, 45, 37, 29, 21, 13, 5, 331e0b9a84aScgd 63, 55, 47, 39, 31, 23, 15, 7, 332e0b9a84aScgd }; 333e0b9a84aScgd 334e0b9a84aScgd /* The final permutation is the inverse of IP - no table is necessary */ 335e0b9a84aScgd 336d7d75e06Sjdolecek static const unsigned char ExpandTr[] = { /* expansion operation */ 337e0b9a84aScgd 32, 1, 2, 3, 4, 5, 338e0b9a84aScgd 4, 5, 6, 7, 8, 9, 339e0b9a84aScgd 8, 9, 10, 11, 12, 13, 340e0b9a84aScgd 12, 13, 14, 15, 16, 17, 341e0b9a84aScgd 16, 17, 18, 19, 20, 21, 342e0b9a84aScgd 20, 21, 22, 23, 24, 25, 343e0b9a84aScgd 24, 25, 26, 27, 28, 29, 344e0b9a84aScgd 28, 29, 30, 31, 32, 1, 345e0b9a84aScgd }; 346e0b9a84aScgd 347d7d75e06Sjdolecek static const unsigned char PC1[] = { /* permuted choice table 1 */ 348e0b9a84aScgd 57, 49, 41, 33, 25, 17, 9, 349e0b9a84aScgd 1, 58, 50, 42, 34, 26, 18, 350e0b9a84aScgd 10, 2, 59, 51, 43, 35, 27, 351e0b9a84aScgd 19, 11, 3, 60, 52, 44, 36, 352e0b9a84aScgd 353e0b9a84aScgd 63, 55, 47, 39, 31, 23, 15, 354e0b9a84aScgd 7, 62, 54, 46, 38, 30, 22, 355e0b9a84aScgd 14, 6, 61, 53, 45, 37, 29, 356e0b9a84aScgd 21, 13, 5, 28, 20, 12, 4, 357e0b9a84aScgd }; 358e0b9a84aScgd 359d7d75e06Sjdolecek static const unsigned char Rotates[] = {/* PC1 rotation schedule */ 360e0b9a84aScgd 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 361e0b9a84aScgd }; 362e0b9a84aScgd 363e0b9a84aScgd /* note: each "row" of PC2 is left-padded with bits that make it invertible */ 364d7d75e06Sjdolecek static const unsigned char PC2[] = { /* permuted choice table 2 */ 365e0b9a84aScgd 9, 18, 14, 17, 11, 24, 1, 5, 366e0b9a84aScgd 22, 25, 3, 28, 15, 6, 21, 10, 367e0b9a84aScgd 35, 38, 23, 19, 12, 4, 26, 8, 368e0b9a84aScgd 43, 54, 16, 7, 27, 20, 13, 2, 369e0b9a84aScgd 370e0b9a84aScgd 0, 0, 41, 52, 31, 37, 47, 55, 371e0b9a84aScgd 0, 0, 30, 40, 51, 45, 33, 48, 372e0b9a84aScgd 0, 0, 44, 49, 39, 56, 34, 53, 373e0b9a84aScgd 0, 0, 46, 42, 50, 36, 29, 32, 374e0b9a84aScgd }; 375e0b9a84aScgd 376d7d75e06Sjdolecek static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */ 377e0b9a84aScgd /* S[1] */ 37831a2bdc6Smikel { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 379e0b9a84aScgd 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 380e0b9a84aScgd 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 38131a2bdc6Smikel 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }, 382e0b9a84aScgd /* S[2] */ 38331a2bdc6Smikel { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 384e0b9a84aScgd 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 385e0b9a84aScgd 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 38631a2bdc6Smikel 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }, 387e0b9a84aScgd /* S[3] */ 38831a2bdc6Smikel { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 389e0b9a84aScgd 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 390e0b9a84aScgd 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 39131a2bdc6Smikel 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }, 392e0b9a84aScgd /* S[4] */ 39331a2bdc6Smikel { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 394e0b9a84aScgd 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 395e0b9a84aScgd 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 39631a2bdc6Smikel 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }, 397e0b9a84aScgd /* S[5] */ 39831a2bdc6Smikel { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 399e0b9a84aScgd 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 400e0b9a84aScgd 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 40131a2bdc6Smikel 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }, 402e0b9a84aScgd /* S[6] */ 40331a2bdc6Smikel { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 404e0b9a84aScgd 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 405e0b9a84aScgd 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 40631a2bdc6Smikel 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }, 407e0b9a84aScgd /* S[7] */ 40831a2bdc6Smikel { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 409e0b9a84aScgd 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 410e0b9a84aScgd 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 41131a2bdc6Smikel 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }, 412e0b9a84aScgd /* S[8] */ 41331a2bdc6Smikel { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 414e0b9a84aScgd 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 415e0b9a84aScgd 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 41631a2bdc6Smikel 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } 417e0b9a84aScgd }; 418e0b9a84aScgd 419d7d75e06Sjdolecek static const unsigned char P32Tr[] = { /* 32-bit permutation function */ 420e0b9a84aScgd 16, 7, 20, 21, 421e0b9a84aScgd 29, 12, 28, 17, 422e0b9a84aScgd 1, 15, 23, 26, 423e0b9a84aScgd 5, 18, 31, 10, 424e0b9a84aScgd 2, 8, 24, 14, 425e0b9a84aScgd 32, 27, 3, 9, 426e0b9a84aScgd 19, 13, 30, 6, 427e0b9a84aScgd 22, 11, 4, 25, 428e0b9a84aScgd }; 429e0b9a84aScgd 430d7d75e06Sjdolecek static const unsigned char CIFP[] = { /* compressed/interleaved permutation */ 431e0b9a84aScgd 1, 2, 3, 4, 17, 18, 19, 20, 432e0b9a84aScgd 5, 6, 7, 8, 21, 22, 23, 24, 433e0b9a84aScgd 9, 10, 11, 12, 25, 26, 27, 28, 434e0b9a84aScgd 13, 14, 15, 16, 29, 30, 31, 32, 435e0b9a84aScgd 436e0b9a84aScgd 33, 34, 35, 36, 49, 50, 51, 52, 437e0b9a84aScgd 37, 38, 39, 40, 53, 54, 55, 56, 438e0b9a84aScgd 41, 42, 43, 44, 57, 58, 59, 60, 439e0b9a84aScgd 45, 46, 47, 48, 61, 62, 63, 64, 440e0b9a84aScgd }; 441e0b9a84aScgd 442d7d75e06Sjdolecek static const unsigned char itoa64[] = /* 0..63 => ascii-64 */ 443e0b9a84aScgd "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 444e0b9a84aScgd 445e0b9a84aScgd 446e0b9a84aScgd /* ===== Tables that are initialized at run time ==================== */ 447e0b9a84aScgd 448e0b9a84aScgd 449e0b9a84aScgd /* Initial key schedule permutation */ 450e0b9a84aScgd static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS]; 451e0b9a84aScgd 452e0b9a84aScgd /* Subsequent key schedule rotation permutations */ 453e0b9a84aScgd static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS]; 454e0b9a84aScgd 455e0b9a84aScgd /* Initial permutation/expansion table */ 456e0b9a84aScgd static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS]; 457e0b9a84aScgd 458e0b9a84aScgd /* Table that combines the S, P, and E operations. */ 459688980ebScgd static int32_t SPE[2][8][64]; 460e0b9a84aScgd 461e0b9a84aScgd /* compressed/interleaved => final permutation table */ 462e0b9a84aScgd static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS]; 463e0b9a84aScgd 464e0b9a84aScgd 465e0b9a84aScgd /* ==================================== */ 466e0b9a84aScgd 467e0b9a84aScgd 468e0b9a84aScgd static C_block constdatablock; /* encryption constant */ 469e0b9a84aScgd static char cryptresult[1+4+4+11+1]; /* encrypted result */ 470e0b9a84aScgd 471aeeea54dSchristos /* 472aeeea54dSchristos * We match the behavior of UFC-crypt on systems where "char" is signed by 473aeeea54dSchristos * default (the majority), regardless of char's signedness on our system. 474aeeea54dSchristos */ 475aeeea54dSchristos static inline int 476aeeea54dSchristos ascii_to_bin(char ch) 477aeeea54dSchristos { 478aeeea54dSchristos signed char sch = ch; 479aeeea54dSchristos int retval; 480aeeea54dSchristos 481aeeea54dSchristos if (sch >= 'a') 482aeeea54dSchristos retval = sch - ('a' - 38); 483aeeea54dSchristos else if (sch >= 'A') 484aeeea54dSchristos retval = sch - ('A' - 12); 485aeeea54dSchristos else 486aeeea54dSchristos retval = sch - '.'; 487aeeea54dSchristos 488aeeea54dSchristos return retval & 0x3f; 489aeeea54dSchristos } 490dbd46365Schristos 491aeeea54dSchristos /* 492aeeea54dSchristos * When we choose to "support" invalid salts, nevertheless disallow those 493aeeea54dSchristos * containing characters that would violate the passwd file format. 494aeeea54dSchristos */ 495aeeea54dSchristos static inline int 496aeeea54dSchristos ascii_is_unsafe(char ch) 497aeeea54dSchristos { 498aeeea54dSchristos return !ch || ch == '\n' || ch == ':'; 499aeeea54dSchristos } 500a46d295dSchristos 501e0b9a84aScgd /* 502c7ab523eSjhigh * We extract the scheme from setting str to allow for 503c7ab523eSjhigh * full scheme name comparison 504c7ab523eSjhigh * Updated to reflect alc suggestion(s) 505c7ab523eSjhigh * 50637a23ecfSmsaitoh * returns boolean 0 on failure, 1 on success, 507c7ab523eSjhigh */ 508c7ab523eSjhigh static int 509c7ab523eSjhigh nondes_scheme_substr(const char * setting,char * scheme, unsigned int len) 510c7ab523eSjhigh { 511c7ab523eSjhigh const char * start; 512c7ab523eSjhigh const char * sep; 513c7ab523eSjhigh 514c7ab523eSjhigh /* initialize head pointer */ 515c7ab523eSjhigh start = setting; 516c7ab523eSjhigh 517c7ab523eSjhigh /* clear out scheme buffer regardless of result */ 518c7ab523eSjhigh memset(scheme, 0, len); 519c7ab523eSjhigh 520c7ab523eSjhigh /* make sure we are working on non-des scheme string */ 521c7ab523eSjhigh if (*start != _PASSWORD_NONDES) { 522c7ab523eSjhigh return 0; 523c7ab523eSjhigh } 524c7ab523eSjhigh 525c7ab523eSjhigh /* increment passed initial _PASSWORD_NONDES */ 526c7ab523eSjhigh start++; 527c7ab523eSjhigh 528c7ab523eSjhigh if ((sep = memchr(start, _PASSWORD_NONDES,len-1)) == NULL) { 529c7ab523eSjhigh return 0; 530c7ab523eSjhigh } 531c7ab523eSjhigh 532c7ab523eSjhigh /* if empty string, we are done */ 533c7ab523eSjhigh if (sep == start) { 534c7ab523eSjhigh return 1; 535c7ab523eSjhigh } 536c7ab523eSjhigh 537c7ab523eSjhigh /* copy scheme substr to buffer */ 538c7ab523eSjhigh memcpy(scheme, start, (size_t)(sep - start)); 539c7ab523eSjhigh 540c7ab523eSjhigh return 1; 541c7ab523eSjhigh } 542c7ab523eSjhigh 543c7ab523eSjhigh /* 544e0b9a84aScgd * Return a pointer to static data consisting of the "setting" 545e0b9a84aScgd * followed by an encryption produced by the "key" and "setting". 546e0b9a84aScgd */ 547e7926f1eSchristos static char * 548dbd46365Schristos __crypt(const char *key, const char *setting) 549e0b9a84aScgd { 55006795b86Slukem char *encp; 551c7ab523eSjhigh char scheme[12]; 55206795b86Slukem int32_t i; 55306795b86Slukem int t; 554c7ab523eSjhigh int r; 555688980ebScgd int32_t salt; 556e0b9a84aScgd int num_iter, salt_size; 557e0b9a84aScgd C_block keyblock, rsltblock; 558e0b9a84aScgd 559ac9fc8f4Sad /* Non-DES encryption schemes hook in here. */ 560ac9fc8f4Sad if (setting[0] == _PASSWORD_NONDES) { 561c7ab523eSjhigh r = nondes_scheme_substr( 562c7ab523eSjhigh setting, scheme, sizeof(scheme)); 563c7ab523eSjhigh 564c7ab523eSjhigh /* return NULL if we are unable to extract substring */ 565c7ab523eSjhigh if (!r) { 566c7ab523eSjhigh return NULL; 567c7ab523eSjhigh } 568c7ab523eSjhigh 569c7ab523eSjhigh /* $2a$ found in bcrypt.c:encode_salt */ 570c7ab523eSjhigh if (strcmp(scheme, "2a") == 0) { 571ac9fc8f4Sad return (__bcrypt(key, setting)); 572c7ab523eSjhigh } else if (strcmp(scheme, "sha1") == 0) { 573c7ab523eSjhigh /* $sha1$ found in crypt.h:SHA1_MAGIC */ 5743a0c68edSsjg return (__crypt_sha1(key, setting)); 575c7ab523eSjhigh } else if (strcmp(scheme, "1") == 0) { 576c7ab523eSjhigh /* $1$ found in pw_gensalt.c:__gensalt_md5 */ 577ac9fc8f4Sad return (__md5crypt(key, setting)); 578b302373fSjhigh #ifdef HAVE_ARGON2 579b302373fSjhigh /* explicit argon2 variant */ 580b302373fSjhigh } else if (strcmp(scheme, "argon2id") == 0) { 581b302373fSjhigh /* $argon2id$ found in pw_gensalt.c:__gensalt_argon2 */ 582b302373fSjhigh return (__crypt_argon2(key, setting)); 583b302373fSjhigh } else if (strcmp(scheme, "argon2i") == 0) { 584b302373fSjhigh /* $argon2i$ found in pw_gensalt.c:__gensalt_argon2 */ 585b302373fSjhigh return (__crypt_argon2(key, setting)); 586b302373fSjhigh } else if (strcmp(scheme, "argon2d") == 0) { 587b302373fSjhigh /* $argon2d$ found in pw_gensalt.c:__gensalt_argon2 */ 588b302373fSjhigh return (__crypt_argon2(key, setting)); 589b302373fSjhigh #endif /* HAVE_ARGON2 */ 590c7ab523eSjhigh } else { 591c7ab523eSjhigh /* invalid scheme, including empty string */ 592c7ab523eSjhigh return NULL; 593ac9fc8f4Sad } 594ac9fc8f4Sad } 595c7ab523eSjhigh /* End non-DES handling */ 596ac9fc8f4Sad 597e0b9a84aScgd for (i = 0; i < 8; i++) { 598e0b9a84aScgd if ((t = 2*(unsigned char)(*key)) != 0) 599e0b9a84aScgd key++; 600e0b9a84aScgd keyblock.b[i] = t; 601e0b9a84aScgd } 602aeeea54dSchristos if (des_setkey((char *)keyblock.b)) 603e0b9a84aScgd return (NULL); 604e0b9a84aScgd 605e0b9a84aScgd encp = &cryptresult[0]; 606e0b9a84aScgd switch (*setting) { 607e0b9a84aScgd case _PASSWORD_EFMT1: 608e0b9a84aScgd /* 609e0b9a84aScgd * Involve the rest of the password 8 characters at a time. 610e0b9a84aScgd */ 611e0b9a84aScgd while (*key) { 612ddb7e7aaSwiz if (des_cipher((char *)(void *)&keyblock, 613ddb7e7aaSwiz (char *)(void *)&keyblock, 0L, 1)) 614e0b9a84aScgd return (NULL); 615e0b9a84aScgd for (i = 0; i < 8; i++) { 616e0b9a84aScgd if ((t = 2*(unsigned char)(*key)) != 0) 617e0b9a84aScgd key++; 618e0b9a84aScgd keyblock.b[i] ^= t; 619e0b9a84aScgd } 620e0b9a84aScgd if (des_setkey((char *)keyblock.b)) 621e0b9a84aScgd return (NULL); 622e0b9a84aScgd } 623e0b9a84aScgd 624e0b9a84aScgd *encp++ = *setting++; 625e0b9a84aScgd 626e0b9a84aScgd /* get iteration count */ 627e0b9a84aScgd num_iter = 0; 628e0b9a84aScgd for (i = 4; --i >= 0; ) { 629aeeea54dSchristos int value = ascii_to_bin(setting[i]); 630aeeea54dSchristos if (itoa64[value] != setting[i]) 631aeeea54dSchristos return NULL; 632aeeea54dSchristos encp[i] = setting[i]; 633aeeea54dSchristos num_iter = (num_iter << 6) | value; 634e0b9a84aScgd } 635aeeea54dSchristos if (num_iter == 0) 636aeeea54dSchristos return NULL; 637e0b9a84aScgd setting += 4; 638e0b9a84aScgd encp += 4; 639e0b9a84aScgd salt_size = 4; 640e0b9a84aScgd break; 641e0b9a84aScgd default: 642e0b9a84aScgd num_iter = 25; 643e0b9a84aScgd salt_size = 2; 644aeeea54dSchristos if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1])) 645aeeea54dSchristos return NULL; 646e0b9a84aScgd } 647e0b9a84aScgd 648e0b9a84aScgd salt = 0; 649e0b9a84aScgd for (i = salt_size; --i >= 0; ) { 650aeeea54dSchristos int value = ascii_to_bin(setting[i]); 651b0ca4d4eSchristos if (salt_size > 2 && itoa64[value] != setting[i]) 652aeeea54dSchristos return NULL; 653aeeea54dSchristos encp[i] = setting[i]; 654aeeea54dSchristos salt = (salt << 6) | value; 655e0b9a84aScgd } 656e0b9a84aScgd encp += salt_size; 657ddb7e7aaSwiz if (des_cipher((char *)(void *)&constdatablock, 658ddb7e7aaSwiz (char *)(void *)&rsltblock, salt, num_iter)) 659e0b9a84aScgd return (NULL); 660e0b9a84aScgd 661e0b9a84aScgd /* 662e0b9a84aScgd * Encode the 64 cipher bits as 11 ascii characters. 663e0b9a84aScgd */ 664688980ebScgd i = ((int32_t)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | 665688980ebScgd rsltblock.b[2]; 666e0b9a84aScgd encp[3] = itoa64[i&0x3f]; i >>= 6; 667e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 668e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 669e0b9a84aScgd encp[0] = itoa64[i]; encp += 4; 670688980ebScgd i = ((int32_t)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | 671688980ebScgd rsltblock.b[5]; 672e0b9a84aScgd encp[3] = itoa64[i&0x3f]; i >>= 6; 673e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 674e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 675e0b9a84aScgd encp[0] = itoa64[i]; encp += 4; 676688980ebScgd i = ((int32_t)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2; 677e0b9a84aScgd encp[2] = itoa64[i&0x3f]; i >>= 6; 678e0b9a84aScgd encp[1] = itoa64[i&0x3f]; i >>= 6; 679e0b9a84aScgd encp[0] = itoa64[i]; 680e0b9a84aScgd 681e0b9a84aScgd encp[3] = 0; 682e0b9a84aScgd 683e0b9a84aScgd return (cryptresult); 684e0b9a84aScgd } 685e0b9a84aScgd 686dbd46365Schristos char * 687dbd46365Schristos crypt(const char *key, const char *salt) 688dbd46365Schristos { 689dbd46365Schristos char *res = __crypt(key, salt); 690b302373fSjhigh 691dbd46365Schristos if (res) 692dbd46365Schristos return res; 693dbd46365Schristos /* How do I handle errors ? Return "*0" or "*1" */ 694dbd46365Schristos return __UNCONST(salt[0] == '*' && salt[1] == '0' ? "*1" : "*0"); 695dbd46365Schristos } 696e0b9a84aScgd 697e0b9a84aScgd /* 698e0b9a84aScgd * The Key Schedule, filled in by des_setkey() or setkey(). 699e0b9a84aScgd */ 700e0b9a84aScgd #define KS_SIZE 16 701e0b9a84aScgd static C_block KS[KS_SIZE]; 702e0b9a84aScgd 703e0b9a84aScgd /* 704e0b9a84aScgd * Set up the key schedule from the key. 705e0b9a84aScgd */ 70631a2bdc6Smikel int 70759153410Sperry des_setkey(const char *key) 708e0b9a84aScgd { 70906795b86Slukem DCL_BLOCK(K, K0, K1); 71065b9988bSdrochner C_block *help, *ptabp; 71106795b86Slukem int i; 712e0b9a84aScgd static int des_ready = 0; 713e0b9a84aScgd 714e0b9a84aScgd if (!des_ready) { 715e0b9a84aScgd init_des(); 716e0b9a84aScgd des_ready = 1; 717e0b9a84aScgd } 718e0b9a84aScgd 71965b9988bSdrochner PERM6464(K,K0,K1,(const unsigned char *)key,(C_block *)PC1ROT); 72065b9988bSdrochner help = &KS[0]; 72165b9988bSdrochner STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help); 722e0b9a84aScgd for (i = 1; i < 16; i++) { 72365b9988bSdrochner help++; 72465b9988bSdrochner STORE(K,K0,K1,*help); 725e0b9a84aScgd ptabp = (C_block *)PC2ROT[Rotates[i]-1]; 72665b9988bSdrochner PERM6464(K,K0,K1,(const unsigned char *)help,ptabp); 72765b9988bSdrochner STORE(K&~0x03030303L, K0&~0x03030303L, K1, *help); 728e0b9a84aScgd } 729e0b9a84aScgd return (0); 730e0b9a84aScgd } 731e0b9a84aScgd 732e0b9a84aScgd /* 733e0b9a84aScgd * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) 73489c5a767Ssoren * iterations of DES, using the given 24-bit salt and the pre-computed key 735e0b9a84aScgd * schedule, and store the resulting 8 chars at "out" (in == out is permitted). 736e0b9a84aScgd * 737e0b9a84aScgd * NOTE: the performance of this routine is critically dependent on your 738e0b9a84aScgd * compiler and machine architecture. 739e0b9a84aScgd */ 74031a2bdc6Smikel int 74159153410Sperry des_cipher(const char *in, char *out, long salt, int num_iter) 742e0b9a84aScgd { 743e0b9a84aScgd /* variables that we want in registers, most important first */ 744e0b9a84aScgd #if defined(pdp11) 7450b7831a3Sperry int j; 746e0b9a84aScgd #endif 7470b7831a3Sperry int32_t L0, L1, R0, R1, k; 7480b7831a3Sperry C_block *kp; 7490b7831a3Sperry int ks_inc, loop_count; 750e0b9a84aScgd C_block B; 751e0b9a84aScgd 752e0b9a84aScgd L0 = salt; 753e0b9a84aScgd TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ 754e0b9a84aScgd 75559695352Smatt #if defined(__vax__) || defined(pdp11) 756e0b9a84aScgd salt = ~salt; /* "x &~ y" is faster than "x & y". */ 757e0b9a84aScgd #define SALT (~salt) 758e0b9a84aScgd #else 759e0b9a84aScgd #define SALT salt 760e0b9a84aScgd #endif 761e0b9a84aScgd 762e0b9a84aScgd #if defined(MUST_ALIGN) 763e0b9a84aScgd B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3]; 764e0b9a84aScgd B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7]; 765e0b9a84aScgd LOAD(L,L0,L1,B); 766e0b9a84aScgd #else 76765b9988bSdrochner LOAD(L,L0,L1,*(const C_block *)in); 768e0b9a84aScgd #endif 769e0b9a84aScgd LOADREG(R,R0,R1,L,L0,L1); 770e0b9a84aScgd L0 &= 0x55555555L; 771e0b9a84aScgd L1 &= 0x55555555L; 7726ab39b67Skamil L0 = ((uint32_t)L0 << 1) | L1; /* L0 is the even-numbered input bits */ 773e0b9a84aScgd R0 &= 0xaaaaaaaaL; 7746ab39b67Skamil R1 = ((uint32_t)R1 >> 1) & 0x55555555L; 775e0b9a84aScgd L1 = R0 | R1; /* L1 is the odd-numbered input bits */ 776e0b9a84aScgd STORE(L,L0,L1,B); 777e0b9a84aScgd PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */ 778e0b9a84aScgd PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */ 779e0b9a84aScgd 780e0b9a84aScgd if (num_iter >= 0) 781e0b9a84aScgd { /* encryption */ 782e0b9a84aScgd kp = &KS[0]; 783e0b9a84aScgd ks_inc = sizeof(*kp); 784e0b9a84aScgd } 785e0b9a84aScgd else 786e0b9a84aScgd { /* decryption */ 7879323d932Sthorpej num_iter = -num_iter; 7889323d932Sthorpej kp = &KS[KS_SIZE-1]; 7899323d932Sthorpej ks_inc = -(long)sizeof(*kp); 790e0b9a84aScgd } 791e0b9a84aScgd 792e0b9a84aScgd while (--num_iter >= 0) { 793e0b9a84aScgd loop_count = 8; 794e0b9a84aScgd do { 795e0b9a84aScgd 796688980ebScgd #define SPTAB(t, i) \ 797688980ebScgd (*(int32_t *)((unsigned char *)t + i*(sizeof(int32_t)/4))) 798e0b9a84aScgd #if defined(gould) 799e0b9a84aScgd /* use this if B.b[i] is evaluated just once ... */ 800e0b9a84aScgd #define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); 801e0b9a84aScgd #else 802e0b9a84aScgd #if defined(pdp11) 803e0b9a84aScgd /* use this if your "long" int indexing is slow */ 804e0b9a84aScgd #define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); 805e0b9a84aScgd #else 80695eeab3bSmikel /* use this if "k" is allocated to a register ... */ 807e0b9a84aScgd #define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); 808e0b9a84aScgd #endif 809e0b9a84aScgd #endif 810e0b9a84aScgd 811e0b9a84aScgd #define CRUNCH(p0, p1, q0, q1) \ 812e0b9a84aScgd k = (q0 ^ q1) & SALT; \ 813e0b9a84aScgd B.b32.i0 = k ^ q0 ^ kp->b32.i0; \ 814e0b9a84aScgd B.b32.i1 = k ^ q1 ^ kp->b32.i1; \ 815e0b9a84aScgd kp = (C_block *)((char *)kp+ks_inc); \ 816e0b9a84aScgd \ 817e0b9a84aScgd DOXOR(p0, p1, 0); \ 818e0b9a84aScgd DOXOR(p0, p1, 1); \ 819e0b9a84aScgd DOXOR(p0, p1, 2); \ 820e0b9a84aScgd DOXOR(p0, p1, 3); \ 821e0b9a84aScgd DOXOR(p0, p1, 4); \ 822e0b9a84aScgd DOXOR(p0, p1, 5); \ 823e0b9a84aScgd DOXOR(p0, p1, 6); \ 824e0b9a84aScgd DOXOR(p0, p1, 7); 825e0b9a84aScgd 826e0b9a84aScgd CRUNCH(L0, L1, R0, R1); 827e0b9a84aScgd CRUNCH(R0, R1, L0, L1); 828e0b9a84aScgd } while (--loop_count != 0); 829e0b9a84aScgd kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE)); 830e0b9a84aScgd 831e0b9a84aScgd 832e0b9a84aScgd /* swap L and R */ 833e0b9a84aScgd L0 ^= R0; L1 ^= R1; 834e0b9a84aScgd R0 ^= L0; R1 ^= L1; 835e0b9a84aScgd L0 ^= R0; L1 ^= R1; 836e0b9a84aScgd } 837e0b9a84aScgd 838e0b9a84aScgd /* store the encrypted (or decrypted) result */ 83996be1c99Skamil L0 = (((uint32_t)L0 >> 3) & 0x0f0f0f0fL) | (((uint32_t)L1 << 1) & 0xf0f0f0f0L); 84096be1c99Skamil L1 = (((uint32_t)R0 >> 3) & 0x0f0f0f0fL) | (((uint32_t)R1 << 1) & 0xf0f0f0f0L); 841e0b9a84aScgd STORE(L,L0,L1,B); 842e0b9a84aScgd PERM6464(L,L0,L1,B.b, (C_block *)CF6464); 843e0b9a84aScgd #if defined(MUST_ALIGN) 844e0b9a84aScgd STORE(L,L0,L1,B); 845e0b9a84aScgd out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3]; 846e0b9a84aScgd out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7]; 847e0b9a84aScgd #else 848e0b9a84aScgd STORE(L,L0,L1,*(C_block *)out); 849e0b9a84aScgd #endif 850e0b9a84aScgd return (0); 851e0b9a84aScgd } 852e0b9a84aScgd 853e0b9a84aScgd 854e0b9a84aScgd /* 855e0b9a84aScgd * Initialize various tables. This need only be done once. It could even be 856e0b9a84aScgd * done at compile time, if the compiler were capable of that sort of thing. 857e0b9a84aScgd */ 858e0b9a84aScgd STATIC 85959153410Sperry init_des(void) 860e0b9a84aScgd { 86106795b86Slukem int i, j; 86206795b86Slukem int32_t k; 86306795b86Slukem int tableno; 864e0b9a84aScgd static unsigned char perm[64], tmp32[32]; /* "static" for speed */ 865e0b9a84aScgd 866e0b9a84aScgd /* 867e0b9a84aScgd * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. 868e0b9a84aScgd */ 869e0b9a84aScgd for (i = 0; i < 64; i++) 870e0b9a84aScgd perm[i] = 0; 871e0b9a84aScgd for (i = 0; i < 64; i++) { 872e0b9a84aScgd if ((k = PC2[i]) == 0) 873e0b9a84aScgd continue; 874e0b9a84aScgd k += Rotates[0]-1; 875e0b9a84aScgd if ((k%28) < Rotates[0]) k -= 28; 876e0b9a84aScgd k = PC1[k]; 877e0b9a84aScgd if (k > 0) { 878e0b9a84aScgd k--; 879e0b9a84aScgd k = (k|07) - (k&07); 880e0b9a84aScgd k++; 881e0b9a84aScgd } 882e0b9a84aScgd perm[i] = k; 883e0b9a84aScgd } 884e0b9a84aScgd #ifdef DEBUG 885e0b9a84aScgd prtab("pc1tab", perm, 8); 886e0b9a84aScgd #endif 887e0b9a84aScgd init_perm(PC1ROT, perm, 8, 8); 888e0b9a84aScgd 889e0b9a84aScgd /* 890e0b9a84aScgd * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. 891e0b9a84aScgd */ 892e0b9a84aScgd for (j = 0; j < 2; j++) { 893e0b9a84aScgd unsigned char pc2inv[64]; 894e0b9a84aScgd for (i = 0; i < 64; i++) 895e0b9a84aScgd perm[i] = pc2inv[i] = 0; 896e0b9a84aScgd for (i = 0; i < 64; i++) { 897e0b9a84aScgd if ((k = PC2[i]) == 0) 898e0b9a84aScgd continue; 899e0b9a84aScgd pc2inv[k-1] = i+1; 900e0b9a84aScgd } 901e0b9a84aScgd for (i = 0; i < 64; i++) { 902e0b9a84aScgd if ((k = PC2[i]) == 0) 903e0b9a84aScgd continue; 904e0b9a84aScgd k += j; 905e0b9a84aScgd if ((k%28) <= j) k -= 28; 906e0b9a84aScgd perm[i] = pc2inv[k]; 907e0b9a84aScgd } 908e0b9a84aScgd #ifdef DEBUG 909e0b9a84aScgd prtab("pc2tab", perm, 8); 910e0b9a84aScgd #endif 911e0b9a84aScgd init_perm(PC2ROT[j], perm, 8, 8); 912e0b9a84aScgd } 913e0b9a84aScgd 914e0b9a84aScgd /* 915e0b9a84aScgd * Bit reverse, then initial permutation, then expansion. 916e0b9a84aScgd */ 917e0b9a84aScgd for (i = 0; i < 8; i++) { 918e0b9a84aScgd for (j = 0; j < 8; j++) { 919e0b9a84aScgd k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1]; 920e0b9a84aScgd if (k > 32) 921e0b9a84aScgd k -= 32; 922e0b9a84aScgd else if (k > 0) 923e0b9a84aScgd k--; 924e0b9a84aScgd if (k > 0) { 925e0b9a84aScgd k--; 926e0b9a84aScgd k = (k|07) - (k&07); 927e0b9a84aScgd k++; 928e0b9a84aScgd } 929e0b9a84aScgd perm[i*8+j] = k; 930e0b9a84aScgd } 931e0b9a84aScgd } 932e0b9a84aScgd #ifdef DEBUG 933e0b9a84aScgd prtab("ietab", perm, 8); 934e0b9a84aScgd #endif 935e0b9a84aScgd init_perm(IE3264, perm, 4, 8); 936e0b9a84aScgd 937e0b9a84aScgd /* 938e0b9a84aScgd * Compression, then final permutation, then bit reverse. 939e0b9a84aScgd */ 940e0b9a84aScgd for (i = 0; i < 64; i++) { 941e0b9a84aScgd k = IP[CIFP[i]-1]; 942e0b9a84aScgd if (k > 0) { 943e0b9a84aScgd k--; 944e0b9a84aScgd k = (k|07) - (k&07); 945e0b9a84aScgd k++; 946e0b9a84aScgd } 947e0b9a84aScgd perm[k-1] = i+1; 948e0b9a84aScgd } 949e0b9a84aScgd #ifdef DEBUG 950e0b9a84aScgd prtab("cftab", perm, 8); 951e0b9a84aScgd #endif 952e0b9a84aScgd init_perm(CF6464, perm, 8, 8); 953e0b9a84aScgd 954e0b9a84aScgd /* 955e0b9a84aScgd * SPE table 956e0b9a84aScgd */ 957e0b9a84aScgd for (i = 0; i < 48; i++) 958e0b9a84aScgd perm[i] = P32Tr[ExpandTr[i]-1]; 959e0b9a84aScgd for (tableno = 0; tableno < 8; tableno++) { 960e0b9a84aScgd for (j = 0; j < 64; j++) { 961e0b9a84aScgd k = (((j >> 0) &01) << 5)| 962e0b9a84aScgd (((j >> 1) &01) << 3)| 963e0b9a84aScgd (((j >> 2) &01) << 2)| 964e0b9a84aScgd (((j >> 3) &01) << 1)| 965e0b9a84aScgd (((j >> 4) &01) << 0)| 966e0b9a84aScgd (((j >> 5) &01) << 4); 967e0b9a84aScgd k = S[tableno][k]; 968e0b9a84aScgd k = (((k >> 3)&01) << 0)| 969e0b9a84aScgd (((k >> 2)&01) << 1)| 970e0b9a84aScgd (((k >> 1)&01) << 2)| 971e0b9a84aScgd (((k >> 0)&01) << 3); 972e0b9a84aScgd for (i = 0; i < 32; i++) 973e0b9a84aScgd tmp32[i] = 0; 974e0b9a84aScgd for (i = 0; i < 4; i++) 975e0b9a84aScgd tmp32[4 * tableno + i] = (k >> i) & 01; 976e0b9a84aScgd k = 0; 977e0b9a84aScgd for (i = 24; --i >= 0; ) 978e0b9a84aScgd k = (k<<1) | tmp32[perm[i]-1]; 979e0b9a84aScgd TO_SIX_BIT(SPE[0][tableno][j], k); 980e0b9a84aScgd k = 0; 981e0b9a84aScgd for (i = 24; --i >= 0; ) 982e0b9a84aScgd k = (k<<1) | tmp32[perm[i+24]-1]; 983e0b9a84aScgd TO_SIX_BIT(SPE[1][tableno][j], k); 984e0b9a84aScgd } 985e0b9a84aScgd } 986e0b9a84aScgd } 987e0b9a84aScgd 988e0b9a84aScgd /* 989e0b9a84aScgd * Initialize "perm" to represent transformation "p", which rearranges 990e0b9a84aScgd * (perhaps with expansion and/or contraction) one packed array of bits 991e0b9a84aScgd * (of size "chars_in" characters) into another array (of size "chars_out" 992e0b9a84aScgd * characters). 993e0b9a84aScgd * 994e0b9a84aScgd * "perm" must be all-zeroes on entry to this routine. 995e0b9a84aScgd */ 996e0b9a84aScgd STATIC 99759153410Sperry init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS], const unsigned char p[64], 99859153410Sperry int chars_in, int chars_out) 999e0b9a84aScgd { 100006795b86Slukem int i, j, k, l; 1001e0b9a84aScgd 1002e0b9a84aScgd for (k = 0; k < chars_out*8; k++) { /* each output bit position */ 1003e0b9a84aScgd l = p[k] - 1; /* where this bit comes from */ 1004e0b9a84aScgd if (l < 0) 1005e0b9a84aScgd continue; /* output bit is always 0 */ 1006e0b9a84aScgd i = l>>LGCHUNKBITS; /* which chunk this bit comes from */ 1007e0b9a84aScgd l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */ 1008e0b9a84aScgd for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */ 1009e0b9a84aScgd if ((j & l) != 0) 1010e0b9a84aScgd perm[i][j].b[k>>3] |= 1<<(k&07); 1011e0b9a84aScgd } 1012e0b9a84aScgd } 1013e0b9a84aScgd } 1014e0b9a84aScgd 1015e0b9a84aScgd /* 1016e0b9a84aScgd * "setkey" routine (for backwards compatibility) 1017e0b9a84aScgd */ 101831a2bdc6Smikel int 101959153410Sperry setkey(const char *key) 1020e0b9a84aScgd { 102106795b86Slukem int i, j, k; 1022e0b9a84aScgd C_block keyblock; 1023e0b9a84aScgd 1024e0b9a84aScgd for (i = 0; i < 8; i++) { 1025e0b9a84aScgd k = 0; 1026e0b9a84aScgd for (j = 0; j < 8; j++) { 1027e0b9a84aScgd k <<= 1; 1028e0b9a84aScgd k |= (unsigned char)*key++; 1029e0b9a84aScgd } 1030e0b9a84aScgd keyblock.b[i] = k; 1031e0b9a84aScgd } 1032e0b9a84aScgd return (des_setkey((char *)keyblock.b)); 1033e0b9a84aScgd } 1034e0b9a84aScgd 1035e0b9a84aScgd /* 1036e0b9a84aScgd * "encrypt" routine (for backwards compatibility) 1037e0b9a84aScgd */ 103831a2bdc6Smikel int 103959153410Sperry encrypt(char *block, int flag) 1040e0b9a84aScgd { 104106795b86Slukem int i, j, k; 1042e0b9a84aScgd C_block cblock; 1043e0b9a84aScgd 1044e0b9a84aScgd for (i = 0; i < 8; i++) { 1045e0b9a84aScgd k = 0; 1046e0b9a84aScgd for (j = 0; j < 8; j++) { 1047e0b9a84aScgd k <<= 1; 1048e0b9a84aScgd k |= (unsigned char)*block++; 1049e0b9a84aScgd } 1050e0b9a84aScgd cblock.b[i] = k; 1051e0b9a84aScgd } 1052e0b9a84aScgd if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1))) 1053e0b9a84aScgd return (1); 1054e0b9a84aScgd for (i = 7; i >= 0; i--) { 1055e0b9a84aScgd k = cblock.b[i]; 1056e0b9a84aScgd for (j = 7; j >= 0; j--) { 1057e0b9a84aScgd *--block = k&01; 1058e0b9a84aScgd k >>= 1; 1059e0b9a84aScgd } 1060e0b9a84aScgd } 1061e0b9a84aScgd return (0); 1062e0b9a84aScgd } 1063e0b9a84aScgd 1064e0b9a84aScgd #ifdef DEBUG 1065e0b9a84aScgd STATIC 106659153410Sperry prtab(const char *s, unsigned char *t, int num_rows) 1067e0b9a84aScgd { 106806795b86Slukem int i, j; 1069e0b9a84aScgd 1070e0b9a84aScgd (void)printf("%s:\n", s); 1071e0b9a84aScgd for (i = 0; i < num_rows; i++) { 1072e0b9a84aScgd for (j = 0; j < 8; j++) { 1073e0b9a84aScgd (void)printf("%3d", t[i*8+j]); 1074e0b9a84aScgd } 1075e0b9a84aScgd (void)printf("\n"); 1076e0b9a84aScgd } 1077e0b9a84aScgd (void)printf("\n"); 1078e0b9a84aScgd } 1079e0b9a84aScgd #endif 10803a0c68edSsjg 10813a0c68edSsjg #if defined(MAIN) || defined(UNIT_TEST) 10823a0c68edSsjg #include <err.h> 10833a0c68edSsjg 10843a0c68edSsjg int 10853a0c68edSsjg main(int argc, char *argv[]) 10863a0c68edSsjg { 10875521b51aSchristos if (argc < 2) { 10885521b51aSchristos fprintf(stderr, "Usage: %s password [salt]\n", getprogname()); 10895521b51aSchristos return EXIT_FAILURE; 10905521b51aSchristos } 10913a0c68edSsjg 10923a0c68edSsjg printf("%s\n", crypt(argv[1], (argc > 2) ? argv[2] : argv[1])); 10935521b51aSchristos return EXIT_SUCCESS; 10943a0c68edSsjg } 10953a0c68edSsjg #endif 1096