/* NOCW */
#include <stdio.h>
#ifdef _OSD_POSIX
# ifndef CHARSET_EBCDIC
#  define CHARSET_EBCDIC 1
# endif
#endif
#ifdef CHARSET_EBCDIC
# include <openssl/ebcdic.h>
#endif

/*
 * This version of crypt has been developed from my MIT compatible DES
 * library. Eric Young (eay@cryptsoft.com)
 */

/*
 * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for
 * shared memory computers. I have included a directive LONGCRYPT to using
 * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it
 * used. The MAXPLEN definition is the maximum of length of password and can
 * changed. I have defined 24.
 */

#include <openssl/crypto.h>
#include "des_locl.h"

/*
 * Added more values to handle illegal salt values the way normal crypt()
 * implementations do.  The patch was sent by Bjorn Gronvall <bg@sics.se>
 */
static unsigned const char con_salt[128] = {
    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
    0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
    0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
    0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
    0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
    0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
    0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
};

static unsigned const char cov_2char[64] = {
    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};

char *DES_crypt(const char *buf, const char *salt)
{
    static char buff[14];

#ifndef CHARSET_EBCDIC
    return (DES_fcrypt(buf, salt, buff));
#else
    char e_salt[2 + 1];
    char e_buf[32 + 1];         /* replace 32 by 8 ? */
    char *ret;

    /* Copy at most 2 chars of salt */
    if ((e_salt[0] = salt[0]) != '\0')
        e_salt[1] = salt[1];

    /* Copy at most 32 chars of password */
    strncpy(e_buf, buf, sizeof(e_buf));

    /* Make sure we have a delimiter */
    e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0';

    /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */
    ebcdic2ascii(e_salt, e_salt, sizeof e_salt);

    /* Convert the cleartext password to ASCII */
    ebcdic2ascii(e_buf, e_buf, sizeof e_buf);

    /* Encrypt it (from/to ASCII) */
    ret = DES_fcrypt(e_buf, e_salt, buff);

    /* Convert the result back to EBCDIC */
    ascii2ebcdic(ret, ret, strlen(ret));

    return ret;
#endif
}

char *DES_fcrypt(const char *buf, const char *salt, char *ret)
{
    unsigned int i, j, x, y;
    DES_LONG Eswap0, Eswap1;
    DES_LONG out[2], ll;
    DES_cblock key;
    DES_key_schedule ks;
    unsigned char bb[9];
    unsigned char *b = bb;
    unsigned char c, u;

    /*
     * eay 25/08/92 If you call crypt("pwd","*") as often happens when you
     * have * as the pwd field in /etc/passwd, the function returns
     * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would
     * crypt to "*".  This was found when replacing the crypt in our shared
     * libraries.  People found that the disabled accounts effectively had no
     * passwd :-(.
     */
#ifndef CHARSET_EBCDIC
    x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]);
    Eswap0 = con_salt[x] << 2;
    x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]);
    Eswap1 = con_salt[x] << 6;
#else
    x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]);
    Eswap0 = con_salt[x] << 2;
    x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]);
    Eswap1 = con_salt[x] << 6;
#endif

    /*
     * EAY r=strlen(buf); r=(r+7)/8;
     */
    for (i = 0; i < 8; i++) {
        c = *(buf++);
        if (!c)
            break;
        key[i] = (c << 1);
    }
    for (; i < 8; i++)
        key[i] = 0;

    DES_set_key_unchecked(&key, &ks);
    fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);

    ll = out[0];
    l2c(ll, b);
    ll = out[1];
    l2c(ll, b);
    y = 0;
    u = 0x80;
    bb[8] = 0;
    for (i = 2; i < 13; i++) {
        c = 0;
        for (j = 0; j < 6; j++) {
            c <<= 1;
            if (bb[y] & u)
                c |= 1;
            u >>= 1;
            if (!u) {
                y++;
                u = 0x80;
            }
        }
        ret[i] = cov_2char[c];
    }
    ret[13] = '\0';
    return (ret);
}
