155714Skris/* NOCW */
255714Skris#include <stdio.h>
355714Skris#ifdef _OSD_POSIX
4296465Sdelphij# ifndef CHARSET_EBCDIC
5296465Sdelphij#  define CHARSET_EBCDIC 1
6296465Sdelphij# endif
755714Skris#endif
855714Skris#ifdef CHARSET_EBCDIC
9296465Sdelphij# include <openssl/ebcdic.h>
1055714Skris#endif
1155714Skris
12296465Sdelphij/*
13296465Sdelphij * This version of crypt has been developed from my MIT compatible DES
14296465Sdelphij * library. Eric Young (eay@cryptsoft.com)
1555714Skris */
1655714Skris
17296465Sdelphij/*
18296465Sdelphij * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for
19296465Sdelphij * shared memory computers. I have included a directive LONGCRYPT to using
20296465Sdelphij * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it
21296465Sdelphij * used. The MAXPLEN definition is the maximum of length of password and can
22296465Sdelphij * changed. I have defined 24.
2355714Skris */
2455714Skris
2555714Skris#include "des_locl.h"
2655714Skris
27296465Sdelphij/*
28296465Sdelphij * Added more values to handle illegal salt values the way normal crypt()
29296465Sdelphij * implementations do.  The patch was sent by Bjorn Gronvall <bg@sics.se>
3055714Skris */
31296465Sdelphijstatic unsigned const char con_salt[128] = {
32296465Sdelphij    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
33296465Sdelphij    0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
34296465Sdelphij    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
35296465Sdelphij    0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
36296465Sdelphij    0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
37296465Sdelphij    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
38296465Sdelphij    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
39296465Sdelphij    0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
40296465Sdelphij    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
41296465Sdelphij    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
42296465Sdelphij    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
43296465Sdelphij    0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
44296465Sdelphij    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
45296465Sdelphij    0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
46296465Sdelphij    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
47296465Sdelphij    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
4855714Skris};
4955714Skris
50296465Sdelphijstatic unsigned const char cov_2char[64] = {
51296465Sdelphij    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
52296465Sdelphij    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
53296465Sdelphij    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
54296465Sdelphij    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
55296465Sdelphij    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
56296465Sdelphij    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
57296465Sdelphij    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
58296465Sdelphij    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
5955714Skris};
6055714Skris
61109998Smarkmchar *DES_crypt(const char *buf, const char *salt)
62296465Sdelphij{
63296465Sdelphij    static char buff[14];
6455714Skris
6555714Skris#ifndef CHARSET_EBCDIC
66296465Sdelphij    return (DES_fcrypt(buf, salt, buff));
6755714Skris#else
68296465Sdelphij    char e_salt[2 + 1];
69296465Sdelphij    char e_buf[32 + 1];         /* replace 32 by 8 ? */
70296465Sdelphij    char *ret;
7155714Skris
72296465Sdelphij    /* Copy at most 2 chars of salt */
73296465Sdelphij    if ((e_salt[0] = salt[0]) != '\0')
74296465Sdelphij        e_salt[1] = salt[1];
7555714Skris
76296465Sdelphij    /* Copy at most 32 chars of password */
77296465Sdelphij    strncpy(e_buf, buf, sizeof(e_buf));
7855714Skris
79296465Sdelphij    /* Make sure we have a delimiter */
80296465Sdelphij    e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0';
8155714Skris
82296465Sdelphij    /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
83296465Sdelphij    ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
8455714Skris
85296465Sdelphij    /* Convert the cleartext password to ASCII */
86296465Sdelphij    ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
8755714Skris
88296465Sdelphij    /* Encrypt it (from/to ASCII) */
89296465Sdelphij    ret = DES_fcrypt(e_buf, e_salt, buff);
9055714Skris
91296465Sdelphij    /* Convert the result back to EBCDIC */
92296465Sdelphij    ascii2ebcdic(ret, ret, strlen(ret));
93296465Sdelphij
94296465Sdelphij    return ret;
9555714Skris#endif
96296465Sdelphij}
9755714Skris
98109998Smarkmchar *DES_fcrypt(const char *buf, const char *salt, char *ret)
99296465Sdelphij{
100296465Sdelphij    unsigned int i, j, x, y;
101296465Sdelphij    DES_LONG Eswap0, Eswap1;
102296465Sdelphij    DES_LONG out[2], ll;
103296465Sdelphij    DES_cblock key;
104296465Sdelphij    DES_key_schedule ks;
105296465Sdelphij    unsigned char bb[9];
106296465Sdelphij    unsigned char *b = bb;
107296465Sdelphij    unsigned char c, u;
10855714Skris
109296465Sdelphij    /*
110296465Sdelphij     * eay 25/08/92 If you call crypt("pwd","*") as often happens when you
111296465Sdelphij     * have * as the pwd field in /etc/passwd, the function returns
112296465Sdelphij     * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would
113296465Sdelphij     * crypt to "*".  This was found when replacing the crypt in our shared
114296465Sdelphij     * libraries.  People found that the disabled accounts effectively had no
115296465Sdelphij     * passwd :-(.
116296465Sdelphij     */
11755714Skris#ifndef CHARSET_EBCDIC
118296465Sdelphij    x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]);
119296465Sdelphij    Eswap0 = con_salt[x] << 2;
120296465Sdelphij    x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]);
121296465Sdelphij    Eswap1 = con_salt[x] << 6;
12255714Skris#else
123296465Sdelphij    x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]);
124296465Sdelphij    Eswap0 = con_salt[x] << 2;
125296465Sdelphij    x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]);
126296465Sdelphij    Eswap1 = con_salt[x] << 6;
12755714Skris#endif
12855714Skris
129296465Sdelphij    /*
130296465Sdelphij     * EAY r=strlen(buf); r=(r+7)/8;
131296465Sdelphij     */
132296465Sdelphij    for (i = 0; i < 8; i++) {
133296465Sdelphij        c = *(buf++);
134296465Sdelphij        if (!c)
135296465Sdelphij            break;
136296465Sdelphij        key[i] = (c << 1);
137296465Sdelphij    }
138296465Sdelphij    for (; i < 8; i++)
139296465Sdelphij        key[i] = 0;
14055714Skris
141296465Sdelphij    DES_set_key_unchecked(&key, &ks);
142296465Sdelphij    fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);
14355714Skris
144296465Sdelphij    ll = out[0];
145296465Sdelphij    l2c(ll, b);
146296465Sdelphij    ll = out[1];
147296465Sdelphij    l2c(ll, b);
148296465Sdelphij    y = 0;
149296465Sdelphij    u = 0x80;
150296465Sdelphij    bb[8] = 0;
151296465Sdelphij    for (i = 2; i < 13; i++) {
152296465Sdelphij        c = 0;
153296465Sdelphij        for (j = 0; j < 6; j++) {
154296465Sdelphij            c <<= 1;
155296465Sdelphij            if (bb[y] & u)
156296465Sdelphij                c |= 1;
157296465Sdelphij            u >>= 1;
158296465Sdelphij            if (!u) {
159296465Sdelphij                y++;
160296465Sdelphij                u = 0x80;
161296465Sdelphij            }
162296465Sdelphij        }
163296465Sdelphij        ret[i] = cov_2char[c];
164296465Sdelphij    }
165296465Sdelphij    ret[13] = '\0';
166296465Sdelphij    return (ret);
167296465Sdelphij}
168