OSDN Git Service

Update my email address. I am no longer andersen@lineo.com
[uclinux-h8/uClibc.git] / libcrypt / des.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * The one and only crypt(3) function.
4  *
5  * This source code is derived from Minix's pwdauth.c, which was based
6  * on Andy Tanenbaum's book "Computer Networks", and then rewritten in
7  * C by Kees J. Bot, 7 Feb 1994.  This code was ported from Minix to
8  * uClibc on June 28, 2001 by Manuel Novoa III, and then reshuffled to
9  * be reentrant by Erik Andersen <andersen@uclibc.org> on June 28, 2001. 
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU Library General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at your
14  * option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
19  * for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  *
25  * Original copyright notice is retained at the end of this file.
26  *
27  */
28
29
30
31 /* This program gets as input the key and salt arguments of the crypt(3)
32  * function as two null terminated strings.  The crypt result is output as
33  * one null terminated string.  Input and output must be <= 1024 characters.
34  * The exit code will be 1 on any error.
35  *
36  * If the key has the form '##name' then the key will be encrypted and the
37  * result checked to be equal to the encrypted password in the shadow password
38  * file.  If equal than '##name' will be returned, otherwise exit code 2.
39  *
40  * Otherwise the key will be encrypted normally and the result returned.
41  *
42  * As a special case, anything matches a null encrypted password to allow
43  * a no-password login.
44  */
45
46 #include <string.h>
47 #include <crypt.h>
48
49 extern char * md5_crypt_r( const char *pw, const char *salt, struct crypt_data * data);
50
51 static const struct ordering InitialTr = { {
52         58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
53         62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
54         57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
55         61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
56 } };
57
58 static const struct ordering FinalTr = { {
59         40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
60         38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
61         36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
62         34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
63 } };
64
65 static const struct ordering swap = { {
66         33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
67         49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
68          1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
69         17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
70 } };
71
72 static const struct ordering KeyTr1 = { {
73         57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
74         10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
75         63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
76         14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
77 } };
78
79 static const struct ordering KeyTr2 = { {
80         14,17,11,24, 1, 5, 3,28,15, 6,21,10,
81         23,19,12, 4,26, 8,16, 7,27,20,13, 2,
82         41,52,31,37,47,55,30,40,51,45,33,48,
83         44,49,39,56,34,53,46,42,50,36,29,32,
84 } };
85
86 static const struct ordering etr = { {
87         32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
88          8, 9,10,11,12,13,12,13,14,15,16,17,
89         16,17,18,19,20,21,20,21,22,23,24,25,
90         24,25,26,27,28,29,28,29,30,31,32, 1,
91 } };
92
93 static const struct ordering ptr = { {
94         16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
95          2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
96 } };
97
98 static const unsigned char s_boxes[8][64] = {
99 {       14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
100          0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
101          4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
102         15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
103 },
104
105 {       15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
106          3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
107          0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
108         13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
109 },
110
111 {       10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
112         13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
113         13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
114          1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
115 },
116
117 {        7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
118         13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
119         10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
120          3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
121 },
122
123 {        2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
124         14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
125          4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
126         11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
127 },
128
129 {       12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
130         10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
131          9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
132          4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
133 },
134
135 {        4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
136         13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
137          1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
138          6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
139 },
140
141 {       13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
142          1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
143          7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
144          2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
145 },
146 };
147
148 static const int rots[] = {
149         1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
150 };
151
152 static void transpose(struct block *data, const struct ordering *t, int n)
153 {
154         struct block x;
155
156         x = *data;
157
158         while (n-- > 0) {
159                 data->b_data[n] = x.b_data[t->o_data[n] - 1];
160         }
161 }
162
163 static void rotate(struct block *key)
164 {
165         unsigned char *p = key->b_data;
166         unsigned char *ep = &(key->b_data[55]);
167         int data0 = key->b_data[0], data28 = key->b_data[28];
168
169         while (p++ < ep) *(p-1) = *p;
170         key->b_data[27] = data0;
171         key->b_data[55] = data28;
172 }
173
174 static void f(int i, struct block *key, struct block *a, struct block *x, struct crypt_data *data)
175 {
176         struct block e, ikey, y;
177         int k;
178         unsigned char *p, *q, *r;
179
180         e = *a;
181         transpose(&e, data->EP, 48);
182         for (k = rots[i]; k; k--) rotate(key);
183         ikey = *key;
184         transpose(&ikey, &KeyTr2, 48);
185         p = &(y.b_data[48]);
186         q = &(e.b_data[48]);
187         r = &(ikey.b_data[48]);
188         while (p > y.b_data) {
189                 *--p = *--q ^ *--r;
190         }
191         q = x->b_data;
192         for (k = 0; k < 8; k++) {
193                 int xb, r;
194
195                 r = *p++ << 5;
196                 r += *p++ << 3;
197                 r += *p++ << 2;
198                 r += *p++ << 1;
199                 r += *p++;
200                 r += *p++ << 4;
201
202                 xb = s_boxes[k][r];
203
204                 *q++ = (xb >> 3) & 1;
205                 *q++ = (xb>>2) & 1;
206                 *q++ = (xb>>1) & 1;
207                 *q++ = (xb & 1);
208         }
209         transpose(x, &ptr, 32);
210 }
211
212 void setkey_r(const char *k, struct crypt_data *data)
213 {
214         struct block *key = &(data->key);
215         memcpy(key, k, (sizeof(struct block)));
216         transpose(key, &KeyTr1, 56);
217 }
218
219 extern void encrypt_r(char *blck, int edflag, struct crypt_data *data)
220 {
221         struct block *key = &(data->key);
222         struct block *p = (struct block *) blck;
223         int i;
224
225         transpose(p, &InitialTr, 64);
226         for (i = 15; i>= 0; i--) {
227                 int j = edflag ? i : 15 - i;
228                 int k;
229                 struct block b, x;
230
231                 b = *p;
232                 for (k = 31; k >= 0; k--) {
233                         p->b_data[k] = b.b_data[k + 32];
234                 }
235                 f(j, key, p, &x, data);
236                 for (k = 31; k >= 0; k--) {
237                         p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
238                 }
239         }
240         transpose(p, &swap, 64);
241         transpose(p, &FinalTr, 64);
242 }
243
244 extern char *crypt_r(const char *pw, const char *salt, struct crypt_data *data)
245 {
246         char pwb[66];
247         char *cp;
248         static char result[16];
249         char *p = pwb;
250         struct ordering new_etr;
251         int i;
252
253         /* First, check if we are supposed to be using the MD5 replacement
254          * instead of DES...  */
255         if (salt[0]=='$' && salt[1]=='1' && salt[2]=='$')
256                 return md5_crypt_r(pw, salt, data);
257
258         data->EP = &etr;
259         while (*pw && p < &pwb[64]) {
260                 int j = 7;
261
262                 while (j--) {
263                         *p++ = (*pw >> j) & 01;
264                 }
265                 pw++;
266                 *p++ = 0;
267         }
268         while (p < &pwb[64]) *p++ = 0;
269
270         setkey_r(p = pwb, data);
271
272         while (p < &pwb[66]) *p++ = 0;
273
274         new_etr = etr;
275         data->EP = &new_etr;
276         if (salt[0] == 0 || salt[1] == 0) salt = "**";
277         for (i = 0; i < 2; i++) {
278                 char c = *salt++;
279                 int j;
280
281                 result[i] = c;
282                 if ( c > 'Z') c -= 6 + 7 + '.'; /* c was a lower case letter */
283                 else if ( c > '9') c -= 7 + '.';/* c was upper case letter */
284                 else c -= '.';                  /* c was digit, '.' or '/'. */
285                                                 /* now, 0 <= c <= 63 */
286                 for (j = 0; j < 6; j++) {
287                         if ((c >> j) & 01) {
288                                 int t = 6*i + j;
289                                 int temp = new_etr.o_data[t];
290                                 new_etr.o_data[t] = new_etr.o_data[t+24];
291                                 new_etr.o_data[t+24] = temp;
292                         }
293                 }
294         }
295
296         if (result[1] == 0) result[1] = result[0];
297
298         for (i = 0; i < 25; i++) encrypt_r(pwb,0, data);
299         data->EP = &etr;
300
301         p = pwb;
302         cp = result+2;
303         while (p < &pwb[66]) {
304                 int c = 0;
305                 int j = 6;
306
307                 while (j--) {
308                         c <<= 1;
309                         c |= *p++;
310                 }
311                 c += '.';               /* becomes >= '.' */
312                 if (c > '9') c += 7;    /* not in [./0-9], becomes upper */
313                 if (c > 'Z') c += 6;    /* not in [A-Z], becomes lower */
314                 *cp++ = c;
315         }
316         *cp = 0;
317         return result;
318 }
319
320
321 /*
322  * Copyright (c) 1987,1997, Prentice Hall
323  * All rights reserved.
324  * 
325  * Redistribution and use of the MINIX operating system in source and
326  * binary forms, with or without modification, are permitted provided
327  * that the following conditions are met:
328  * 
329  * Redistributions of source code must retain the above copyright
330  * notice, this list of conditions and the following disclaimer.
331  * 
332  * Redistributions in binary form must reproduce the above
333  * copyright notice, this list of conditions and the following
334  * disclaimer in the documentation and/or other materials provided
335  * with the distribution.
336  * 
337  * Neither the name of Prentice Hall nor the names of the software
338  * authors or contributors may be used to endorse or promote
339  * products derived from this software without specific prior
340  * written permission.
341  * 
342  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
343  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
344  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
345  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
346  * IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
347  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
348  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
349  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
350  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
351  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
352  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
353  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
354  *
355  */
356
357