1 /* vi: set sw=4 ts=4: */
3 * The one and only crypt(3) function.
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.
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.
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
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
25 * Original copyright notice is retained at the end of this file.
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.
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.
40 * Otherwise the key will be encrypted normally and the result returned.
42 * As a special case, anything matches a null encrypted password to allow
43 * a no-password login.
49 extern char * md5_crypt_r( const char *pw, const char *salt, struct crypt_data * data);
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
148 static const int rots[] = {
149 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
152 static void transpose(struct block *data, const struct ordering *t, int n)
159 data->b_data[n] = x.b_data[t->o_data[n] - 1];
163 static void rotate(struct block *key)
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];
169 while (p++ < ep) *(p-1) = *p;
170 key->b_data[27] = data0;
171 key->b_data[55] = data28;
174 static void f(int i, struct block *key, struct block *a, struct block *x, struct crypt_data *data)
176 struct block e, ikey, y;
178 unsigned char *p, *q, *r;
181 transpose(&e, data->EP, 48);
182 for (k = rots[i]; k; k--) rotate(key);
184 transpose(&ikey, &KeyTr2, 48);
187 r = &(ikey.b_data[48]);
188 while (p > y.b_data) {
192 for (k = 0; k < 8; k++) {
204 *q++ = (xb >> 3) & 1;
209 transpose(x, &ptr, 32);
212 void setkey_r(const char *k, struct crypt_data *data)
214 struct block *key = &(data->key);
215 memcpy(key, k, (sizeof(struct block)));
216 transpose(key, &KeyTr1, 56);
219 extern void encrypt_r(char *blck, int edflag, struct crypt_data *data)
221 struct block *key = &(data->key);
222 struct block *p = (struct block *) blck;
225 transpose(p, &InitialTr, 64);
226 for (i = 15; i>= 0; i--) {
227 int j = edflag ? i : 15 - i;
232 for (k = 31; k >= 0; k--) {
233 p->b_data[k] = b.b_data[k + 32];
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];
240 transpose(p, &swap, 64);
241 transpose(p, &FinalTr, 64);
244 extern char *crypt_r(const char *pw, const char *salt, struct crypt_data *data)
248 static char result[16];
250 struct ordering new_etr;
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);
259 while (*pw && p < &pwb[64]) {
263 *p++ = (*pw >> j) & 01;
268 while (p < &pwb[64]) *p++ = 0;
270 setkey_r(p = pwb, data);
272 while (p < &pwb[66]) *p++ = 0;
276 if (salt[0] == 0 || salt[1] == 0) salt = "**";
277 for (i = 0; i < 2; i++) {
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++) {
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;
296 if (result[1] == 0) result[1] = result[0];
298 for (i = 0; i < 25; i++) encrypt_r(pwb,0, data);
303 while (p < &pwb[66]) {
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 */
322 * Copyright (c) 1987,1997, Prentice Hall
323 * All rights reserved.
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:
329 * Redistributions of source code must retain the above copyright
330 * notice, this list of conditions and the following disclaimer.
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.
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.
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.