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