Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * FreeSec: libcrypt for NetBSD
3 : : *
4 : : * contrib/pgcrypto/crypt-des.c
5 : : *
6 : : * Copyright (c) 1994 David Burren
7 : : * All rights reserved.
8 : : *
9 : : * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
10 : : * this file should now *only* export crypt(), in order to make
11 : : * binaries of libcrypt exportable from the USA
12 : : *
13 : : * Adapted for FreeBSD-4.0 by Mark R V Murray
14 : : * this file should now *only* export px_crypt_des(), in order to make
15 : : * a module that can be optionally included in libcrypt.
16 : : *
17 : : * Redistribution and use in source and binary forms, with or without
18 : : * modification, are permitted provided that the following conditions
19 : : * are met:
20 : : * 1. Redistributions of source code must retain the above copyright
21 : : * notice, this list of conditions and the following disclaimer.
22 : : * 2. Redistributions in binary form must reproduce the above copyright
23 : : * notice, this list of conditions and the following disclaimer in the
24 : : * documentation and/or other materials provided with the distribution.
25 : : * 3. Neither the name of the author nor the names of other contributors
26 : : * may be used to endorse or promote products derived from this software
27 : : * without specific prior written permission.
28 : : *
29 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
30 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
33 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 : : * SUCH DAMAGE.
40 : : *
41 : : * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $
42 : : *
43 : : * This is an original implementation of the DES and the crypt(3) interfaces
44 : : * by David Burren <davidb@werj.com.au>.
45 : : *
46 : : * An excellent reference on the underlying algorithm (and related
47 : : * algorithms) is:
48 : : *
49 : : * B. Schneier, Applied Cryptography: protocols, algorithms,
50 : : * and source code in C, John Wiley & Sons, 1994.
51 : : *
52 : : * Note that in that book's description of DES the lookups for the initial,
53 : : * pbox, and final permutations are inverted (this has been brought to the
54 : : * attention of the author). A list of errata for this book has been
55 : : * posted to the sci.crypt newsgroup by the author and is available for FTP.
56 : : *
57 : : * ARCHITECTURE ASSUMPTIONS:
58 : : * It is assumed that the 8-byte arrays passed by reference can be
59 : : * addressed as arrays of uint32's (ie. the CPU is not picky about
60 : : * alignment).
61 : : */
62 : :
63 : : #include "postgres.h"
64 : : #include "miscadmin.h"
65 : : #include "port/pg_bswap.h"
66 : :
67 : : #include "px-crypt.h"
68 : :
69 : : #define _PASSWORD_EFMT1 '_'
70 : :
71 : : static const char _crypt_a64[] =
72 : : "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
73 : :
74 : : static uint8 IP[64] = {
75 : : 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
76 : : 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
77 : : 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
78 : : 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
79 : : };
80 : :
81 : : static uint8 inv_key_perm[64];
82 : : static uint8 u_key_perm[56];
83 : : static uint8 key_perm[56] = {
84 : : 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
85 : : 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
86 : : 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
87 : : 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
88 : : };
89 : :
90 : : static uint8 key_shifts[16] = {
91 : : 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
92 : : };
93 : :
94 : : static uint8 inv_comp_perm[56];
95 : : static uint8 comp_perm[48] = {
96 : : 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
97 : : 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
98 : : 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
99 : : 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
100 : : };
101 : :
102 : : /*
103 : : * No E box is used, as it's replaced by some ANDs, shifts, and ORs.
104 : : */
105 : :
106 : : static uint8 u_sbox[8][64];
107 : : static uint8 sbox[8][64] = {
108 : : {
109 : : 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
110 : : 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
111 : : 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
112 : : 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
113 : : },
114 : : {
115 : : 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
116 : : 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
117 : : 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
118 : : 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
119 : : },
120 : : {
121 : : 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
122 : : 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
123 : : 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
124 : : 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
125 : : },
126 : : {
127 : : 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
128 : : 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
129 : : 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
130 : : 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
131 : : },
132 : : {
133 : : 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
134 : : 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
135 : : 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
136 : : 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
137 : : },
138 : : {
139 : : 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
140 : : 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
141 : : 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
142 : : 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
143 : : },
144 : : {
145 : : 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
146 : : 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
147 : : 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
148 : : 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
149 : : },
150 : : {
151 : : 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
152 : : 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
153 : : 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
154 : : 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
155 : : }
156 : : };
157 : :
158 : : static uint8 un_pbox[32];
159 : : static uint8 pbox[32] = {
160 : : 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
161 : : 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
162 : : };
163 : :
164 : : static uint32 _crypt_bits32[32] =
165 : : {
166 : : 0x80000000, 0x40000000, 0x20000000, 0x10000000,
167 : : 0x08000000, 0x04000000, 0x02000000, 0x01000000,
168 : : 0x00800000, 0x00400000, 0x00200000, 0x00100000,
169 : : 0x00080000, 0x00040000, 0x00020000, 0x00010000,
170 : : 0x00008000, 0x00004000, 0x00002000, 0x00001000,
171 : : 0x00000800, 0x00000400, 0x00000200, 0x00000100,
172 : : 0x00000080, 0x00000040, 0x00000020, 0x00000010,
173 : : 0x00000008, 0x00000004, 0x00000002, 0x00000001
174 : : };
175 : :
176 : : static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
177 : :
178 : : static uint32 saltbits;
179 : : static long old_salt;
180 : : static uint32 *bits28,
181 : : *bits24;
182 : : static uint8 init_perm[64],
183 : : final_perm[64];
184 : : static uint32 en_keysl[16],
185 : : en_keysr[16];
186 : : static uint32 de_keysl[16],
187 : : de_keysr[16];
188 : : static int des_initialised = 0;
189 : : static uint8 m_sbox[4][4096];
190 : : static uint32 psbox[4][256];
191 : : static uint32 ip_maskl[8][256],
192 : : ip_maskr[8][256];
193 : : static uint32 fp_maskl[8][256],
194 : : fp_maskr[8][256];
195 : : static uint32 key_perm_maskl[8][128],
196 : : key_perm_maskr[8][128];
197 : : static uint32 comp_maskl[8][128],
198 : : comp_maskr[8][128];
199 : : static uint32 old_rawkey0,
200 : : old_rawkey1;
201 : :
202 : : static inline int
8272 bruce@momjian.us 203 :CBC 72 : ascii_to_bin(char ch)
204 : : {
205 [ - + ]: 72 : if (ch > 'z')
2432 peter_e@gmx.net 206 :UBC 0 : return 0;
8272 bruce@momjian.us 207 [ + + ]:CBC 72 : if (ch >= 'a')
208 : 17 : return (ch - 'a' + 38);
209 [ - + ]: 55 : if (ch > 'Z')
2432 peter_e@gmx.net 210 :UBC 0 : return 0;
8272 bruce@momjian.us 211 [ + + ]:CBC 55 : if (ch >= 'A')
212 : 13 : return (ch - 'A' + 12);
213 [ - + ]: 42 : if (ch > '9')
2432 peter_e@gmx.net 214 :UBC 0 : return 0;
8272 bruce@momjian.us 215 [ + + ]:CBC 42 : if (ch >= '.')
216 : 29 : return (ch - '.');
2432 peter_e@gmx.net 217 : 13 : return 0;
218 : : }
219 : :
220 : : static void
7111 tgl@sss.pgh.pa.us 221 : 2 : des_init(void)
222 : : {
223 : : int i,
224 : : j,
225 : : b,
226 : : k,
227 : : inbit,
228 : : obit;
229 : : uint32 *p,
230 : : *il,
231 : : *ir,
232 : : *fl,
233 : : *fr;
234 : :
8272 bruce@momjian.us 235 : 2 : old_rawkey0 = old_rawkey1 = 0L;
236 : 2 : saltbits = 0L;
237 : 2 : old_salt = 0L;
238 : 2 : bits24 = (bits28 = _crypt_bits32 + 4) + 4;
239 : :
240 : : /*
241 : : * Invert the S-boxes, reordering the input bits.
242 : : */
243 [ + + ]: 18 : for (i = 0; i < 8; i++)
244 [ + + ]: 1040 : for (j = 0; j < 64; j++)
245 : : {
246 : 1024 : b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
247 : 1024 : u_sbox[i][j] = sbox[i][b];
248 : : }
249 : :
250 : : /*
251 : : * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
252 : : * 12 bits of the S-box input.
253 : : */
254 [ + + ]: 10 : for (b = 0; b < 4; b++)
255 [ + + ]: 520 : for (i = 0; i < 64; i++)
256 [ + + ]: 33280 : for (j = 0; j < 64; j++)
257 : 32768 : m_sbox[b][(i << 6) | j] =
258 : 32768 : (u_sbox[(b << 1)][i] << 4) |
259 : 32768 : u_sbox[(b << 1) + 1][j];
260 : :
261 : : /*
262 : : * Set up the initial & final permutations into a useful form, and
263 : : * initialise the inverted key permutation.
264 : : */
265 [ + + ]: 130 : for (i = 0; i < 64; i++)
266 : : {
267 : 128 : init_perm[final_perm[i] = IP[i] - 1] = i;
268 : 128 : inv_key_perm[i] = 255;
269 : : }
270 : :
271 : : /*
272 : : * Invert the key permutation and initialise the inverted key compression
273 : : * permutation.
274 : : */
275 [ + + ]: 114 : for (i = 0; i < 56; i++)
276 : : {
277 : 112 : u_key_perm[i] = key_perm[i] - 1;
278 : 112 : inv_key_perm[key_perm[i] - 1] = i;
279 : 112 : inv_comp_perm[i] = 255;
280 : : }
281 : :
282 : : /*
283 : : * Invert the key compression permutation.
284 : : */
285 [ + + ]: 98 : for (i = 0; i < 48; i++)
286 : 96 : inv_comp_perm[comp_perm[i] - 1] = i;
287 : :
288 : : /*
289 : : * Set up the OR-mask arrays for the initial and final permutations, and
290 : : * for the key initial and compression permutations.
291 : : */
292 [ + + ]: 18 : for (k = 0; k < 8; k++)
293 : : {
294 [ + + ]: 4112 : for (i = 0; i < 256; i++)
295 : : {
296 : 4096 : *(il = &ip_maskl[k][i]) = 0L;
297 : 4096 : *(ir = &ip_maskr[k][i]) = 0L;
298 : 4096 : *(fl = &fp_maskl[k][i]) = 0L;
299 : 4096 : *(fr = &fp_maskr[k][i]) = 0L;
300 [ + + ]: 36864 : for (j = 0; j < 8; j++)
301 : : {
302 : 32768 : inbit = 8 * k + j;
303 [ + + ]: 32768 : if (i & _crypt_bits8[j])
304 : : {
305 [ + + ]: 16384 : if ((obit = init_perm[inbit]) < 32)
306 : 8192 : *il |= _crypt_bits32[obit];
307 : : else
308 : 8192 : *ir |= _crypt_bits32[obit - 32];
309 [ + + ]: 16384 : if ((obit = final_perm[inbit]) < 32)
310 : 8192 : *fl |= _crypt_bits32[obit];
311 : : else
312 : 8192 : *fr |= _crypt_bits32[obit - 32];
313 : : }
314 : : }
315 : : }
316 [ + + ]: 2064 : for (i = 0; i < 128; i++)
317 : : {
318 : 2048 : *(il = &key_perm_maskl[k][i]) = 0L;
319 : 2048 : *(ir = &key_perm_maskr[k][i]) = 0L;
320 [ + + ]: 16384 : for (j = 0; j < 7; j++)
321 : : {
322 : 14336 : inbit = 8 * k + j;
323 [ + + ]: 14336 : if (i & _crypt_bits8[j + 1])
324 : : {
325 [ - + ]: 7168 : if ((obit = inv_key_perm[inbit]) == 255)
8272 bruce@momjian.us 326 :UBC 0 : continue;
8272 bruce@momjian.us 327 [ + + ]:CBC 7168 : if (obit < 28)
328 : 3584 : *il |= bits28[obit];
329 : : else
330 : 3584 : *ir |= bits28[obit - 28];
331 : : }
332 : : }
333 : 2048 : *(il = &comp_maskl[k][i]) = 0L;
334 : 2048 : *(ir = &comp_maskr[k][i]) = 0L;
335 [ + + ]: 16384 : for (j = 0; j < 7; j++)
336 : : {
337 : 14336 : inbit = 7 * k + j;
338 [ + + ]: 14336 : if (i & _crypt_bits8[j + 1])
339 : : {
340 [ + + ]: 7168 : if ((obit = inv_comp_perm[inbit]) == 255)
341 : 1024 : continue;
342 [ + + ]: 6144 : if (obit < 24)
343 : 3072 : *il |= bits24[obit];
344 : : else
345 : 3072 : *ir |= bits24[obit - 24];
346 : : }
347 : : }
348 : : }
349 : : }
350 : :
351 : : /*
352 : : * Invert the P-box permutation, and convert into OR-masks for handling
353 : : * the output of the S-box arrays setup above.
354 : : */
355 [ + + ]: 66 : for (i = 0; i < 32; i++)
356 : 64 : un_pbox[pbox[i] - 1] = i;
357 : :
358 [ + + ]: 10 : for (b = 0; b < 4; b++)
359 [ + + ]: 2056 : for (i = 0; i < 256; i++)
360 : : {
361 : 2048 : *(p = &psbox[b][i]) = 0L;
362 [ + + ]: 18432 : for (j = 0; j < 8; j++)
363 : : {
364 [ + + ]: 16384 : if (i & _crypt_bits8[j])
365 : 8192 : *p |= _crypt_bits32[un_pbox[8 * b + j]];
366 : : }
367 : : }
368 : :
369 : 2 : des_initialised = 1;
370 : 2 : }
371 : :
372 : : static void
373 : 13 : setup_salt(long salt)
374 : : {
375 : : uint32 obit,
376 : : saltbit;
377 : : int i;
378 : :
379 [ + + ]: 13 : if (salt == old_salt)
380 : 6 : return;
381 : 7 : old_salt = salt;
382 : :
383 : 7 : saltbits = 0L;
384 : 7 : saltbit = 1;
385 : 7 : obit = 0x800000;
386 [ + + ]: 175 : for (i = 0; i < 24; i++)
387 : : {
388 [ + + ]: 168 : if (salt & saltbit)
389 : 56 : saltbits |= obit;
390 : 168 : saltbit <<= 1;
391 : 168 : obit >>= 1;
392 : : }
393 : : }
394 : :
395 : : static int
396 : 15 : des_setkey(const char *key)
397 : : {
398 : : uint32 k0,
399 : : k1,
400 : : rawkey0,
401 : : rawkey1;
402 : : int shifts,
403 : : round;
404 : :
405 [ - + ]: 15 : if (!des_initialised)
8272 bruce@momjian.us 406 :UBC 0 : des_init();
407 : :
2387 andres@anarazel.de 408 :CBC 15 : rawkey0 = pg_ntoh32(*(const uint32 *) key);
409 : 15 : rawkey1 = pg_ntoh32(*(const uint32 *) (key + 4));
410 : :
8272 bruce@momjian.us 411 [ + + ]: 15 : if ((rawkey0 | rawkey1)
412 [ + + ]: 13 : && rawkey0 == old_rawkey0
413 [ + - ]: 6 : && rawkey1 == old_rawkey1)
414 : : {
415 : : /*
416 : : * Already setup for this key. This optimization fails on a zero key
417 : : * (which is weak and has bad parity anyway) in order to simplify the
418 : : * starting conditions.
419 : : */
2432 peter_e@gmx.net 420 : 6 : return 0;
421 : : }
8272 bruce@momjian.us 422 : 9 : old_rawkey0 = rawkey0;
423 : 9 : old_rawkey1 = rawkey1;
424 : :
425 : : /*
426 : : * Do key permutation and split into two 28-bit subkeys.
427 : : */
428 : 9 : k0 = key_perm_maskl[0][rawkey0 >> 25]
429 : 9 : | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
430 : 9 : | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
431 : 9 : | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
432 : 9 : | key_perm_maskl[4][rawkey1 >> 25]
433 : 9 : | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
434 : 9 : | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
435 : 9 : | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
436 : 9 : k1 = key_perm_maskr[0][rawkey0 >> 25]
437 : 9 : | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
438 : 9 : | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
439 : 9 : | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
440 : 9 : | key_perm_maskr[4][rawkey1 >> 25]
441 : 9 : | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
442 : 9 : | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
443 : 9 : | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
444 : :
445 : : /*
446 : : * Rotate subkeys and do compression permutation.
447 : : */
448 : 9 : shifts = 0;
449 [ + + ]: 153 : for (round = 0; round < 16; round++)
450 : : {
451 : : uint32 t0,
452 : : t1;
453 : :
454 : 144 : shifts += key_shifts[round];
455 : :
456 : 144 : t0 = (k0 << shifts) | (k0 >> (28 - shifts));
457 : 144 : t1 = (k1 << shifts) | (k1 >> (28 - shifts));
458 : :
459 : 144 : de_keysl[15 - round] =
460 : 144 : en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
461 : 144 : | comp_maskl[1][(t0 >> 14) & 0x7f]
462 : 144 : | comp_maskl[2][(t0 >> 7) & 0x7f]
463 : 144 : | comp_maskl[3][t0 & 0x7f]
464 : 144 : | comp_maskl[4][(t1 >> 21) & 0x7f]
465 : 144 : | comp_maskl[5][(t1 >> 14) & 0x7f]
466 : 144 : | comp_maskl[6][(t1 >> 7) & 0x7f]
467 : 144 : | comp_maskl[7][t1 & 0x7f];
468 : :
469 : 144 : de_keysr[15 - round] =
470 : 144 : en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
471 : 144 : | comp_maskr[1][(t0 >> 14) & 0x7f]
472 : 144 : | comp_maskr[2][(t0 >> 7) & 0x7f]
473 : 144 : | comp_maskr[3][t0 & 0x7f]
474 : 144 : | comp_maskr[4][(t1 >> 21) & 0x7f]
475 : 144 : | comp_maskr[5][(t1 >> 14) & 0x7f]
476 : 144 : | comp_maskr[6][(t1 >> 7) & 0x7f]
477 : 144 : | comp_maskr[7][t1 & 0x7f];
478 : : }
2432 peter_e@gmx.net 479 : 9 : return 0;
480 : : }
481 : :
482 : : static int
8207 bruce@momjian.us 483 : 13 : do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
484 : : {
485 : : /*
486 : : * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
487 : : */
488 : : uint32 l,
489 : : r,
490 : : *kl,
491 : : *kr,
492 : : *kl1,
493 : : *kr1;
494 : : uint32 f,
495 : : r48l,
496 : : r48r;
497 : : int round;
498 : :
8272 499 [ + + ]: 13 : if (count == 0)
2432 peter_e@gmx.net 500 : 2 : return 1;
8272 bruce@momjian.us 501 [ + - ]: 11 : else if (count > 0)
502 : : {
503 : : /*
504 : : * Encrypting
505 : : */
506 : 11 : kl1 = en_keysl;
507 : 11 : kr1 = en_keysr;
508 : : }
509 : : else
510 : : {
511 : : /*
512 : : * Decrypting
513 : : */
8272 bruce@momjian.us 514 :UBC 0 : count = -count;
515 : 0 : kl1 = de_keysl;
516 : 0 : kr1 = de_keysr;
517 : : }
518 : :
519 : : /*
520 : : * Do initial permutation (IP).
521 : : */
8272 bruce@momjian.us 522 :CBC 11 : l = ip_maskl[0][l_in >> 24]
523 : 11 : | ip_maskl[1][(l_in >> 16) & 0xff]
524 : 11 : | ip_maskl[2][(l_in >> 8) & 0xff]
525 : 11 : | ip_maskl[3][l_in & 0xff]
526 : 11 : | ip_maskl[4][r_in >> 24]
527 : 11 : | ip_maskl[5][(r_in >> 16) & 0xff]
528 : 11 : | ip_maskl[6][(r_in >> 8) & 0xff]
529 : 11 : | ip_maskl[7][r_in & 0xff];
530 : 11 : r = ip_maskr[0][l_in >> 24]
531 : 11 : | ip_maskr[1][(l_in >> 16) & 0xff]
532 : 11 : | ip_maskr[2][(l_in >> 8) & 0xff]
533 : 11 : | ip_maskr[3][l_in & 0xff]
534 : 11 : | ip_maskr[4][r_in >> 24]
535 : 11 : | ip_maskr[5][(r_in >> 16) & 0xff]
536 : 11 : | ip_maskr[6][(r_in >> 8) & 0xff]
537 : 11 : | ip_maskr[7][r_in & 0xff];
538 : :
539 [ + + ]: 4290 : while (count--)
540 : : {
3031 alvherre@alvh.no-ip. 541 [ - + ]: 4279 : CHECK_FOR_INTERRUPTS();
542 : :
543 : : /*
544 : : * Do each round.
545 : : */
8272 bruce@momjian.us 546 : 4279 : kl = kl1;
547 : 4279 : kr = kr1;
548 : 4279 : round = 16;
549 [ + + ]: 72743 : while (round--)
550 : : {
551 : : /*
552 : : * Expand R to 48 bits (simulate the E-box).
553 : : */
554 : 68464 : r48l = ((r & 0x00000001) << 23)
555 : 68464 : | ((r & 0xf8000000) >> 9)
556 : 68464 : | ((r & 0x1f800000) >> 11)
557 : 68464 : | ((r & 0x01f80000) >> 13)
558 : 68464 : | ((r & 0x001f8000) >> 15);
559 : :
560 : 68464 : r48r = ((r & 0x0001f800) << 7)
561 : 68464 : | ((r & 0x00001f80) << 5)
562 : 68464 : | ((r & 0x000001f8) << 3)
563 : 68464 : | ((r & 0x0000001f) << 1)
564 : 68464 : | ((r & 0x80000000) >> 31);
565 : :
566 : : /*
567 : : * Do salting for crypt() and friends, and XOR with the permuted
568 : : * key.
569 : : */
570 : 68464 : f = (r48l ^ r48r) & saltbits;
571 : 68464 : r48l ^= f ^ *kl++;
572 : 68464 : r48r ^= f ^ *kr++;
573 : :
574 : : /*
575 : : * Do sbox lookups (which shrink it back to 32 bits) and do the
576 : : * pbox permutation at the same time.
577 : : */
578 : 68464 : f = psbox[0][m_sbox[0][r48l >> 12]]
579 : 68464 : | psbox[1][m_sbox[1][r48l & 0xfff]]
580 : 68464 : | psbox[2][m_sbox[2][r48r >> 12]]
581 : 68464 : | psbox[3][m_sbox[3][r48r & 0xfff]];
582 : :
583 : : /*
584 : : * Now that we've permuted things, complete f().
585 : : */
586 : 68464 : f ^= l;
587 : 68464 : l = r;
588 : 68464 : r = f;
589 : : }
590 : 4279 : r = l;
591 : 4279 : l = f;
592 : : }
593 : :
594 : : /*
595 : : * Do final permutation (inverse of IP).
596 : : */
597 : 11 : *l_out = fp_maskl[0][l >> 24]
598 : 11 : | fp_maskl[1][(l >> 16) & 0xff]
599 : 11 : | fp_maskl[2][(l >> 8) & 0xff]
600 : 11 : | fp_maskl[3][l & 0xff]
601 : 11 : | fp_maskl[4][r >> 24]
602 : 11 : | fp_maskl[5][(r >> 16) & 0xff]
603 : 11 : | fp_maskl[6][(r >> 8) & 0xff]
604 : 11 : | fp_maskl[7][r & 0xff];
605 : 11 : *r_out = fp_maskr[0][l >> 24]
606 : 11 : | fp_maskr[1][(l >> 16) & 0xff]
607 : 11 : | fp_maskr[2][(l >> 8) & 0xff]
608 : 11 : | fp_maskr[3][l & 0xff]
609 : 11 : | fp_maskr[4][r >> 24]
610 : 11 : | fp_maskr[5][(r >> 16) & 0xff]
611 : 11 : | fp_maskr[6][(r >> 8) & 0xff]
612 : 11 : | fp_maskr[7][r & 0xff];
2432 peter_e@gmx.net 613 : 11 : return 0;
614 : : }
615 : :
616 : : static int
8272 bruce@momjian.us 617 : 1 : des_cipher(const char *in, char *out, long salt, int count)
618 : : {
619 : : uint32 buffer[2];
620 : : uint32 l_out,
621 : : r_out,
622 : : rawl,
623 : : rawr;
624 : : int retval;
625 : :
626 [ - + ]: 1 : if (!des_initialised)
8272 bruce@momjian.us 627 :UBC 0 : des_init();
628 : :
8272 bruce@momjian.us 629 :CBC 1 : setup_salt(salt);
630 : :
631 : : /* copy data to avoid assuming input is word-aligned */
8217 tgl@sss.pgh.pa.us 632 : 1 : memcpy(buffer, in, sizeof(buffer));
633 : :
2387 andres@anarazel.de 634 : 1 : rawl = pg_ntoh32(buffer[0]);
635 : 1 : rawr = pg_ntoh32(buffer[1]);
636 : :
8272 bruce@momjian.us 637 : 1 : retval = do_des(rawl, rawr, &l_out, &r_out, count);
3108 noah@leadboat.com 638 [ - + ]: 1 : if (retval)
2432 peter_e@gmx.net 639 :UBC 0 : return retval;
640 : :
2387 andres@anarazel.de 641 :CBC 1 : buffer[0] = pg_hton32(l_out);
642 : 1 : buffer[1] = pg_hton32(r_out);
643 : :
644 : : /* copy data to avoid assuming output is word-aligned */
8217 tgl@sss.pgh.pa.us 645 : 1 : memcpy(out, buffer, sizeof(buffer));
646 : :
2432 peter_e@gmx.net 647 : 1 : return retval;
648 : : }
649 : :
650 : : char *
8272 bruce@momjian.us 651 : 14 : px_crypt_des(const char *key, const char *setting)
652 : : {
653 : : int i;
654 : : uint32 count,
655 : : salt,
656 : : l,
657 : : r0,
658 : : r1,
659 : : keybuf[2];
660 : : char *p;
661 : : uint8 *q;
662 : : static char output[21];
663 : :
664 [ + + ]: 14 : if (!des_initialised)
665 : 2 : des_init();
666 : :
667 : :
668 : : /*
669 : : * Copy the key, shifting each character up by one bit and padding with
670 : : * zeros.
671 : : */
672 : 14 : q = (uint8 *) keybuf;
673 [ + + ]: 126 : while (q - (uint8 *) keybuf - 8)
674 : : {
4337 tgl@sss.pgh.pa.us 675 : 112 : *q++ = *key << 1;
676 [ + + ]: 112 : if (*key != '\0')
8272 bruce@momjian.us 677 : 84 : key++;
678 : : }
6777 tgl@sss.pgh.pa.us 679 [ - + ]: 14 : if (des_setkey((char *) keybuf))
2432 peter_e@gmx.net 680 :UBC 0 : return NULL;
681 : :
682 : : #ifndef DISABLE_XDES
8272 bruce@momjian.us 683 [ + + ]:CBC 14 : if (*setting == _PASSWORD_EFMT1)
684 : : {
685 : : /*
686 : : * "new"-style: setting must be a 9-character (underscore, then 4
687 : : * bytes of count, then 4 bytes of salt) string. See CRYPT(3) under
688 : : * the "Extended crypt" heading for further details.
689 : : *
690 : : * Unlimited characters of the input key are used. This is known as
691 : : * the "Extended crypt" DES method.
692 : : *
693 : : */
3114 noah@leadboat.com 694 [ + + ]: 9 : if (strlen(setting) < 9)
695 [ + - ]: 1 : ereport(ERROR,
696 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
697 : : errmsg("invalid salt")));
698 : :
8272 bruce@momjian.us 699 [ + + ]: 40 : for (i = 1, count = 0L; i < 5; i++)
700 : 32 : count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
701 : :
702 [ + + ]: 40 : for (i = 5, salt = 0L; i < 9; i++)
703 : 32 : salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
704 : :
705 [ + + ]: 9 : while (*key)
706 : : {
707 : : /*
708 : : * Encrypt the key with itself.
709 : : */
6777 tgl@sss.pgh.pa.us 710 [ - + ]: 1 : if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1))
2432 peter_e@gmx.net 711 :UBC 0 : return NULL;
712 : :
713 : : /*
714 : : * And XOR with the next 8 characters of the key.
715 : : */
8272 bruce@momjian.us 716 :CBC 1 : q = (uint8 *) keybuf;
717 [ + + + - ]: 9 : while (q - (uint8 *) keybuf - 8 && *key)
718 : 8 : *q++ ^= *key++ << 1;
719 : :
6777 tgl@sss.pgh.pa.us 720 [ - + ]: 1 : if (des_setkey((char *) keybuf))
2432 peter_e@gmx.net 721 :UBC 0 : return NULL;
722 : : }
1343 peter@eisentraut.org 723 :CBC 8 : strlcpy(output, setting, 10);
724 : :
725 : : /*
726 : : * Double check that we weren't given a short setting. If we were, the
727 : : * above code will probably have created weird values for count and
728 : : * salt, but we don't really care. Just make sure the output string
729 : : * doesn't have an extra NUL in it.
730 : : */
8272 bruce@momjian.us 731 : 8 : p = output + strlen(output);
732 : : }
733 : : else
734 : : #endif /* !DISABLE_XDES */
735 : : {
736 : : /*
737 : : * "old"-style: setting - 2 bytes of salt key - only up to the first 8
738 : : * characters of the input key are used.
739 : : */
740 : 5 : count = 25;
741 : :
3114 noah@leadboat.com 742 [ + + ]: 5 : if (strlen(setting) < 2)
743 [ + - ]: 1 : ereport(ERROR,
744 : : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
745 : : errmsg("invalid salt")));
746 : :
8272 bruce@momjian.us 747 : 4 : salt = (ascii_to_bin(setting[1]) << 6)
748 : 4 : | ascii_to_bin(setting[0]);
749 : :
750 : 4 : output[0] = setting[0];
751 : :
752 : : /*
753 : : * If the encrypted password that the salt was extracted from is only
754 : : * 1 character long, the salt will be corrupted. We need to ensure
755 : : * that the output string doesn't have an extra NUL in it!
756 : : */
757 [ + - ]: 4 : output[1] = setting[1] ? setting[1] : output[0];
758 : :
759 : 4 : p = output + 2;
760 : : }
761 : 12 : setup_salt(salt);
762 : :
763 : : /*
764 : : * Do it.
765 : : */
766 [ + + ]: 12 : if (do_des(0L, 0L, &r0, &r1, count))
2432 peter_e@gmx.net 767 : 2 : return NULL;
768 : :
769 : : /*
770 : : * Now encode the result...
771 : : */
8272 bruce@momjian.us 772 : 10 : l = (r0 >> 8);
773 : 10 : *p++ = _crypt_a64[(l >> 18) & 0x3f];
774 : 10 : *p++ = _crypt_a64[(l >> 12) & 0x3f];
775 : 10 : *p++ = _crypt_a64[(l >> 6) & 0x3f];
776 : 10 : *p++ = _crypt_a64[l & 0x3f];
777 : :
778 : 10 : l = (r0 << 16) | ((r1 >> 16) & 0xffff);
779 : 10 : *p++ = _crypt_a64[(l >> 18) & 0x3f];
780 : 10 : *p++ = _crypt_a64[(l >> 12) & 0x3f];
781 : 10 : *p++ = _crypt_a64[(l >> 6) & 0x3f];
782 : 10 : *p++ = _crypt_a64[l & 0x3f];
783 : :
784 : 10 : l = r1 << 2;
785 : 10 : *p++ = _crypt_a64[(l >> 12) & 0x3f];
786 : 10 : *p++ = _crypt_a64[(l >> 6) & 0x3f];
787 : 10 : *p++ = _crypt_a64[l & 0x3f];
788 : 10 : *p = 0;
789 : :
2432 peter_e@gmx.net 790 : 10 : return output;
791 : : }
|