ofcrypt.c revision 1.1 1 1.1 christos /* NOCW */
2 1.1 christos #include <stdio.h>
3 1.1 christos
4 1.1 christos /* This version of crypt has been developed from my MIT compatible
5 1.1 christos * DES library.
6 1.1 christos * Eric Young (eay (at) cryptsoft.com)
7 1.1 christos */
8 1.1 christos
9 1.1 christos /* Modification by Jens Kupferschmidt (Cu)
10 1.1 christos * I have included directive PARA for shared memory computers.
11 1.1 christos * I have included a directive LONGCRYPT to using this routine to cipher
12 1.1 christos * passwords with more than 8 bytes like HP-UX 10.x it used. The MAXPLEN
13 1.1 christos * definition is the maximum of length of password and can changed. I have
14 1.1 christos * defined 24.
15 1.1 christos */
16 1.1 christos
17 1.1 christos #include "des_locl.h"
18 1.1 christos
19 1.1 christos /* Added more values to handle illegal salt values the way normal
20 1.1 christos * crypt() implementations do. The patch was sent by
21 1.1 christos * Bjorn Gronvall <bg (at) sics.se>
22 1.1 christos */
23 1.1 christos static unsigned const char con_salt[128]={
24 1.1 christos 0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
25 1.1 christos 0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
26 1.1 christos 0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
27 1.1 christos 0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
28 1.1 christos 0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
29 1.1 christos 0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
30 1.1 christos 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
31 1.1 christos 0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
32 1.1 christos 0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
33 1.1 christos 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
34 1.1 christos 0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
35 1.1 christos 0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
36 1.1 christos 0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
37 1.1 christos 0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
38 1.1 christos 0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
39 1.1 christos 0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
40 1.1 christos };
41 1.1 christos
42 1.1 christos static unsigned const char cov_2char[64]={
43 1.1 christos 0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
44 1.1 christos 0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
45 1.1 christos 0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
46 1.1 christos 0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
47 1.1 christos 0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
48 1.1 christos 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
49 1.1 christos 0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
50 1.1 christos 0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
51 1.1 christos };
52 1.1 christos
53 1.1 christos void fcrypt_body(DES_LONG *out,des_key_schedule ks,
54 1.1 christos DES_LONG Eswap0, DES_LONG Eswap1);
55 1.1 christos
56 1.1 christos char *des_crypt(const char *buf, const char *salt)
57 1.1 christos {
58 1.1 christos static char buff[14];
59 1.1 christos
60 1.1 christos #ifndef CHARSET_EBCDIC
61 1.1 christos return(des_fcrypt(buf,salt,buff));
62 1.1 christos #else
63 1.1 christos char e_salt[2+1];
64 1.1 christos char e_buf[32+1]; /* replace 32 by 8 ? */
65 1.1 christos char *ret;
66 1.1 christos
67 1.1 christos /* Copy at most 2 chars of salt */
68 1.1 christos if ((e_salt[0] = salt[0]) != '\0')
69 1.1 christos e_salt[1] = salt[1];
70 1.1 christos
71 1.1 christos /* Copy at most 32 chars of password */
72 1.1 christos strncpy (e_buf, buf, sizeof(e_buf));
73 1.1 christos
74 1.1 christos /* Make sure we have a delimiter */
75 1.1 christos e_salt[sizeof(e_salt)-1] = e_buf[sizeof(e_buf)-1] = '\0';
76 1.1 christos
77 1.1 christos /* Convert the e_salt to ASCII, as that's what des_fcrypt works on */
78 1.1 christos ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
79 1.1 christos
80 1.1 christos /* Convert the cleartext password to ASCII */
81 1.1 christos ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
82 1.1 christos
83 1.1 christos /* Encrypt it (from/to ASCII) */
84 1.1 christos ret = des_fcrypt(e_buf,e_salt,buff);
85 1.1 christos
86 1.1 christos /* Convert the result back to EBCDIC */
87 1.1 christos ascii2ebcdic(ret, ret, strlen(ret));
88 1.1 christos
89 1.1 christos return ret;
90 1.1 christos #endif
91 1.1 christos }
92 1.1 christos
93 1.1 christos
94 1.1 christos char *des_fcrypt(const char *buf, const char *salt, char *ret)
95 1.1 christos {
96 1.1 christos unsigned int i,j,x,y;
97 1.1 christos DES_LONG Eswap0,Eswap1;
98 1.1 christos DES_LONG out[2],ll;
99 1.1 christos des_cblock key;
100 1.1 christos des_key_schedule ks;
101 1.1 christos unsigned char bb[9];
102 1.1 christos unsigned char *b=bb;
103 1.1 christos unsigned char c,u;
104 1.1 christos
105 1.1 christos /* eay 25/08/92
106 1.1 christos * If you call crypt("pwd","*") as often happens when you
107 1.1 christos * have * as the pwd field in /etc/passwd, the function
108 1.1 christos * returns *\0XXXXXXXXX
109 1.1 christos * The \0 makes the string look like * so the pwd "*" would
110 1.1 christos * crypt to "*". This was found when replacing the crypt in
111 1.1 christos * our shared libraries. People found that the disabled
112 1.1 christos * accounts effectively had no passwd :-(. */
113 1.1 christos #ifndef CHARSET_EBCDIC
114 1.1 christos x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
115 1.1 christos Eswap0=con_salt[x]<<2;
116 1.1 christos x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
117 1.1 christos Eswap1=con_salt[x]<<6;
118 1.1 christos #else
119 1.1 christos x=ret[0]=((salt[0] == '\0')?os_toascii['A']:salt[0]);
120 1.1 christos Eswap0=con_salt[x]<<2;
121 1.1 christos x=ret[1]=((salt[1] == '\0')?os_toascii['A']:salt[1]);
122 1.1 christos Eswap1=con_salt[x]<<6;
123 1.1 christos #endif
124 1.1 christos
125 1.1 christos /* EAY
126 1.1 christos r=strlen(buf);
127 1.1 christos r=(r+7)/8;
128 1.1 christos */
129 1.1 christos for (i=0; i<8; i++)
130 1.1 christos {
131 1.1 christos c= *(buf++);
132 1.1 christos if (!c) break;
133 1.1 christos key[i]=(c<<1);
134 1.1 christos }
135 1.1 christos for (; i<8; i++)
136 1.1 christos key[i]=0;
137 1.1 christos
138 1.1 christos des_set_key_unchecked(&key,ks);
139 1.1 christos fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
140 1.1 christos
141 1.1 christos ll=out[0]; l2c(ll,b);
142 1.1 christos ll=out[1]; l2c(ll,b);
143 1.1 christos y=0;
144 1.1 christos u=0x80;
145 1.1 christos bb[8]=0;
146 1.1 christos for (i=2; i<13; i++)
147 1.1 christos {
148 1.1 christos c=0;
149 1.1 christos for (j=0; j<6; j++)
150 1.1 christos {
151 1.1 christos c<<=1;
152 1.1 christos if (bb[y] & u) c|=1;
153 1.1 christos u>>=1;
154 1.1 christos if (!u)
155 1.1 christos {
156 1.1 christos y++;
157 1.1 christos u=0x80;
158 1.1 christos }
159 1.1 christos }
160 1.1 christos ret[i]=cov_2char[c];
161 1.1 christos }
162 1.1 christos ret[13]='\0';
163 1.1 christos return(ret);
164 1.1 christos }
165 1.1 christos
166