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