1 /* crypto/des/fcrypt.c */
2 /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@mincom.oz.au).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@mincom.oz.au).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@mincom.oz.au)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 
61 /* Eric Young.
62  * This version of crypt has been developed from my MIT compatible
63  * DES library.
64  * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
65  * eay@mincom.oz.au or eay@psych.psy.uq.oz.au
66  */
67 
68 /* Modification by Jens Kupferschmidt (Cu)
69  * I have included directive _DES_PARA for shared memory computers.
70  * I have included a directive LONGCRYPT to using this routine to cipher
71  * passwords with more than 8 bytes like HP-UX 10.x it used. The MAXPLEN
72  * definition is the maximum of length of password and can changed. I have
73  * defined 24.
74  */
75 
76 #define FCRYPT_MOD(R,u,t,E0,E1,tmp) \
77 	u=R>>16; \
78 	t=R^u; \
79 	u=t&E0; t=t&E1; \
80 	tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
81 	tmp=(t<<16); t^=R^s[S+1]; t^=tmp
82 
83 #define DES_FCRYPT
84 #include "des_locl.h"
85 #undef DES_FCRYPT
86 
87 #undef PERM_OP
88 #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
89 	(b)^=(t),\
90 	(a)^=((t)<<(n)))
91 
92 #undef HPERM_OP
93 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
94 	(a)=(a)^(t)^(t>>(16-(n))))\
95 
96 #ifdef _DES_PARA
97 #define STATIC
98 #else
99 #define STATIC	static
100 #endif
101 
102 #ifndef _DES_NOPROTO
103 
104 STATIC int fcrypt_body(DES_LONG *out0, DES_LONG *out1,
105 	des_key_schedule ks, DES_LONG Eswap0, DES_LONG Eswap1);
106 
107 #else
108 
109 STATIC int fcrypt_body();
110 
111 #endif
112 
113 /* Added more values to handle illegal salt values the way normal
114  * crypt() implementations do.  The patch was sent by
115  * Bjorn Gronvall <bg@sics.se>
116  */
117 static unsigned const char con_salt[128]={
118 0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
119 0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
120 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
121 0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
122 0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
123 0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
124 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
125 0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
126 0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
127 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
128 0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
129 0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
130 0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
131 0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
132 0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
133 0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
134 };
135 
136 static unsigned const char cov_2char[64]={
137 0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
138 0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
139 0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
140 0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
141 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
142 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
143 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
144 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
145 };
146 
147 #ifndef _DES_NOPROTO
148 char *des_crypt(const char *buf,const char *salt);
149 #else
150 char *des_crypt();
151 #endif
152 
des_crypt(buf,salt)153 char *des_crypt(buf,salt)
154 const char *buf;
155 const char *salt;
156 	{
157 	static char buff[14];
158 
159 	return(des_fcrypt(buf,salt,buff));
160 	}
161 
162 
des_fcrypt(buf,salt,ret)163 char *des_fcrypt(buf,salt,ret)
164 const char *buf;
165 const char *salt;
166 char *ret;
167 	{
168 	unsigned int i,j,x,y;
169 	DES_LONG Eswap0,Eswap1;
170 	DES_LONG out[2],ll;
171 	des_cblock key;
172 	des_key_schedule ks;
173 	unsigned char bb[9];
174 	unsigned char *b=bb;
175 	unsigned char c,u;
176 
177 	/* eay 25/08/92
178 	 * If you call des_crypt("pwd","*") as often happens when you
179 	 * have * as the pwd field in /etc/passwd, the function
180 	 * returns *\0XXXXXXXXX
181 	 * The \0 makes the string look like * so the pwd "*" would
182 	 * crypt to "*".  This was found when replacing the crypt in
183 	 * our shared libraries.  People found that the disbled
184 	 * accounts effectivly had no passwd :-(. */
185 	x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
186 	Eswap0=con_salt[x]<<2;
187 	x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
188 	Eswap1=con_salt[x]<<6;
189 
190 /* EAY
191 r=strlen(buf);
192 r=(r+7)/8;
193 */
194 	for (i=0; i<8; i++)
195 		{
196 		c= *(buf++);
197 		if (!c) break;
198 		key[i]=(c<<1);
199 		}
200 	for (; i<8; i++)
201 		key[i]=0;
202 
203 	des_set_key((des_cblock *)(key),ks);
204 	fcrypt_body(&(out[0]),&(out[1]),ks,Eswap0,Eswap1);
205 
206 	ll=out[0]; l2c(ll,b);
207 	ll=out[1]; l2c(ll,b);
208 	y=0;
209 	u=0x80;
210 	bb[8]=0;
211 	for (i=2; i<13; i++)
212 		{
213 		c=0;
214 		for (j=0; j<6; j++)
215 			{
216 			c<<=1;
217 			if (bb[y] & u) c|=1;
218 			u>>=1;
219 			if (!u)
220 				{
221 				y++;
222 				u=0x80;
223 				}
224 			}
225 		ret[i]=cov_2char[c];
226 		}
227 	ret[13]='\0';
228 	return(ret);
229 	}
230 
fcrypt_body(out0,out1,ks,Eswap0,Eswap1)231 STATIC int fcrypt_body(out0, out1, ks, Eswap0, Eswap1)
232 DES_LONG *out0;
233 DES_LONG *out1;
234 des_key_schedule ks;
235 DES_LONG Eswap0;
236 DES_LONG Eswap1;
237 	{
238 	register DES_LONG l,r,t,u;
239 #ifdef DES_PTR
240 	register unsigned char *des_SP=(unsigned char *)des_SPtrans;
241 #endif
242 	register DES_LONG *s;
243 	register int j;
244 	register DES_LONG E0,E1;
245 
246 	l=0;
247 	r=0;
248 
249 	s=(DES_LONG *)ks;
250 	E0=Eswap0;
251 	E1=Eswap1;
252 
253 	for (j=0; j<25; j++)
254 		{
255 #ifdef DES_UNROLL
256 		register int i;
257 
258 		for (i=0; i<32; i+=8)
259 			{
260 			D_ENCRYPT(l,r,i+0); /*  1 */
261 			D_ENCRYPT(r,l,i+2); /*  2 */
262 			D_ENCRYPT(l,r,i+4); /*  3 */
263 			D_ENCRYPT(r,l,i+6); /*  4 */
264 			}
265 #else
266 		D_ENCRYPT(l,r, 0); /*  1 */
267 		D_ENCRYPT(r,l, 2); /*  2 */
268 		D_ENCRYPT(l,r, 4); /*  3 */
269 		D_ENCRYPT(r,l, 6); /*  4 */
270 		D_ENCRYPT(l,r, 8); /*  5 */
271 		D_ENCRYPT(r,l,10); /*  6 */
272 		D_ENCRYPT(l,r,12); /*  7 */
273 		D_ENCRYPT(r,l,14); /*  8 */
274 		D_ENCRYPT(l,r,16); /*  9 */
275 		D_ENCRYPT(r,l,18); /*  10 */
276 		D_ENCRYPT(l,r,20); /*  11 */
277 		D_ENCRYPT(r,l,22); /*  12 */
278 		D_ENCRYPT(l,r,24); /*  13 */
279 		D_ENCRYPT(r,l,26); /*  14 */
280 		D_ENCRYPT(l,r,28); /*  15 */
281 		D_ENCRYPT(r,l,30); /*  16 */
282 #endif
283 		t=l;
284 		l=r;
285 		r=t;
286 		}
287 	l=ROTATE(l,3)&0xffffffffL;
288 	r=ROTATE(r,3)&0xffffffffL;
289 
290 	PERM_OP(l,r,t, 1,0x55555555L);
291 	PERM_OP(r,l,t, 8,0x00ff00ffL);
292 	PERM_OP(l,r,t, 2,0x33333333L);
293 	PERM_OP(r,l,t,16,0x0000ffffL);
294 	PERM_OP(l,r,t, 4,0x0f0f0f0fL);
295 
296 	*out0=r;
297 	*out1=l;
298 	return(0);
299 	}
300 
301