155714Skris/* NOCW */
255714Skris#include <stdio.h>
355714Skris#ifdef _OSD_POSIX
4296341Sdelphij# ifndef CHARSET_EBCDIC
5296341Sdelphij#  define CHARSET_EBCDIC 1
6296341Sdelphij# endif
755714Skris#endif
855714Skris#ifdef CHARSET_EBCDIC
9296341Sdelphij# include <openssl/ebcdic.h>
1055714Skris#endif
1155714Skris
12296341Sdelphij/*
13296341Sdelphij * This version of crypt has been developed from my MIT compatible DES
14296341Sdelphij * library. Eric Young (eay@cryptsoft.com)
1555714Skris */
1655714Skris
17296341Sdelphij/*
18296341Sdelphij * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for
19296341Sdelphij * shared memory computers. I have included a directive LONGCRYPT to using
20296341Sdelphij * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it
21296341Sdelphij * used. The MAXPLEN definition is the maximum of length of password and can
22296341Sdelphij * changed. I have defined 24.
2355714Skris */
2455714Skris
2555714Skris#include "des_locl.h"
2655714Skris
27296341Sdelphij/*
28296341Sdelphij * Added more values to handle illegal salt values the way normal crypt()
29296341Sdelphij * implementations do.  The patch was sent by Bjorn Gronvall <bg@sics.se>
3055714Skris */
31296341Sdelphijstatic unsigned const char con_salt[128] = {
32296341Sdelphij    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
33296341Sdelphij    0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
34296341Sdelphij    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
35296341Sdelphij    0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
36296341Sdelphij    0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
37296341Sdelphij    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
38296341Sdelphij    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
39296341Sdelphij    0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
40296341Sdelphij    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
41296341Sdelphij    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
42296341Sdelphij    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
43296341Sdelphij    0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
44296341Sdelphij    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
45296341Sdelphij    0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
46296341Sdelphij    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
47296341Sdelphij    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
4855714Skris};
4955714Skris
50296341Sdelphijstatic unsigned const char cov_2char[64] = {
51296341Sdelphij    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
52296341Sdelphij    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
53296341Sdelphij    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
54296341Sdelphij    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
55296341Sdelphij    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
56296341Sdelphij    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
57296341Sdelphij    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
58296341Sdelphij    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
5955714Skris};
6055714Skris
61109998Smarkmchar *DES_crypt(const char *buf, const char *salt)
62296341Sdelphij{
63296341Sdelphij    static char buff[14];
6455714Skris
6555714Skris#ifndef CHARSET_EBCDIC
66296341Sdelphij    return (DES_fcrypt(buf, salt, buff));
6755714Skris#else
68296341Sdelphij    char e_salt[2 + 1];
69296341Sdelphij    char e_buf[32 + 1];         /* replace 32 by 8 ? */
70296341Sdelphij    char *ret;
7155714Skris
72296341Sdelphij    /* Copy at most 2 chars of salt */
73296341Sdelphij    if ((e_salt[0] = salt[0]) != '\0')
74296341Sdelphij        e_salt[1] = salt[1];
7555714Skris
76296341Sdelphij    /* Copy at most 32 chars of password */
77296341Sdelphij    strncpy(e_buf, buf, sizeof(e_buf));
7855714Skris
79296341Sdelphij    /* Make sure we have a delimiter */
80296341Sdelphij    e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0';
8155714Skris
82296341Sdelphij    /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
83296341Sdelphij    ebcdic2ascii(e_salt, e_salt, sizeof e_salt);
8455714Skris
85296341Sdelphij    /* Convert the cleartext password to ASCII */
86296341Sdelphij    ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
8755714Skris
88296341Sdelphij    /* Encrypt it (from/to ASCII) */
89296341Sdelphij    ret = DES_fcrypt(e_buf, e_salt, buff);
9055714Skris
91296341Sdelphij    /* Convert the result back to EBCDIC */
92296341Sdelphij    ascii2ebcdic(ret, ret, strlen(ret));
93296341Sdelphij
94296341Sdelphij    return ret;
9555714Skris#endif
96296341Sdelphij}
9755714Skris
98109998Smarkmchar *DES_fcrypt(const char *buf, const char *salt, char *ret)
99296341Sdelphij{
100296341Sdelphij    unsigned int i, j, x, y;
101296341Sdelphij    DES_LONG Eswap0, Eswap1;
102296341Sdelphij    DES_LONG out[2], ll;
103296341Sdelphij    DES_cblock key;
104296341Sdelphij    DES_key_schedule ks;
105296341Sdelphij    unsigned char bb[9];
106296341Sdelphij    unsigned char *b = bb;
107296341Sdelphij    unsigned char c, u;
10855714Skris
109296341Sdelphij    /*
110296341Sdelphij     * eay 25/08/92 If you call crypt("pwd","*") as often happens when you
111296341Sdelphij     * have * as the pwd field in /etc/passwd, the function returns
112296341Sdelphij     * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would
113296341Sdelphij     * crypt to "*".  This was found when replacing the crypt in our shared
114296341Sdelphij     * libraries.  People found that the disabled accounts effectively had no
115296341Sdelphij     * passwd :-(.
116296341Sdelphij     */
11755714Skris#ifndef CHARSET_EBCDIC
118296341Sdelphij    x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]);
119296341Sdelphij    Eswap0 = con_salt[x] << 2;
120296341Sdelphij    x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]);
121296341Sdelphij    Eswap1 = con_salt[x] << 6;
12255714Skris#else
123296341Sdelphij    x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]);
124296341Sdelphij    Eswap0 = con_salt[x] << 2;
125296341Sdelphij    x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]);
126296341Sdelphij    Eswap1 = con_salt[x] << 6;
12755714Skris#endif
12855714Skris
129296341Sdelphij    /*
130296341Sdelphij     * EAY r=strlen(buf); r=(r+7)/8;
131296341Sdelphij     */
132296341Sdelphij    for (i = 0; i < 8; i++) {
133296341Sdelphij        c = *(buf++);
134296341Sdelphij        if (!c)
135296341Sdelphij            break;
136296341Sdelphij        key[i] = (c << 1);
137296341Sdelphij    }
138296341Sdelphij    for (; i < 8; i++)
139296341Sdelphij        key[i] = 0;
14055714Skris
141296341Sdelphij    DES_set_key_unchecked(&key, &ks);
142296341Sdelphij    fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);
14355714Skris
144296341Sdelphij    ll = out[0];
145296341Sdelphij    l2c(ll, b);
146296341Sdelphij    ll = out[1];
147296341Sdelphij    l2c(ll, b);
148296341Sdelphij    y = 0;
149296341Sdelphij    u = 0x80;
150296341Sdelphij    bb[8] = 0;
151296341Sdelphij    for (i = 2; i < 13; i++) {
152296341Sdelphij        c = 0;
153296341Sdelphij        for (j = 0; j < 6; j++) {
154296341Sdelphij            c <<= 1;
155296341Sdelphij            if (bb[y] & u)
156296341Sdelphij                c |= 1;
157296341Sdelphij            u >>= 1;
158296341Sdelphij            if (!u) {
159296341Sdelphij                y++;
160296341Sdelphij                u = 0x80;
161296341Sdelphij            }
162296341Sdelphij        }
163296341Sdelphij        ret[i] = cov_2char[c];
164296341Sdelphij    }
165296341Sdelphij    ret[13] = '\0';
166296341Sdelphij    return (ret);
167296341Sdelphij}
168