1: /* 2: ** crypto.c Crypto extension to pidentd. 3: ** 4: ** This file is in the public domain. -- Planar 1994.02.21 5: ** 6: ** Crypto routines. 7: */ 8: 9: #ifdef INCLUDE_CRYPT 10: 11: #ifdef NeXT31 12: # include <libc.h> 13: #endif 14: 15: #include <stdio.h> 16: 17: #include <sys/types.h> 18: #include <netinet/in.h> 19: 20: #ifndef HPUX7 21: # include <arpa/inet.h> 22: #endif 23: 24: #include <sys/stat.h> 25: #include <sys/time.h> 26: 27: #include <des.h> 28: 29: typedef unsigned short int_16; 30: typedef unsigned int int_32; 31: 32: struct info 33: { 34: int_32 checksum; 35: int_16 random; 36: int_16 uid; 37: int_32 date; 38: int_32 ip_local; 39: int_32 ip_remote; 40: int_16 port_local; 41: int_16 port_remote; 42: }; 43: 44: typedef union data 45: { 46: struct info fields; 47: int_32 longs[6]; 48: unsigned char chars[24]; 49: } data; 50: 51: static char result[33]; 52: des_key_schedule sched; 53: 54: char to_asc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 55: 56: char to_bin[] = 57: { 58: 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 59: 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 60: 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 61: 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 62: 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 63: 0x80, 0x80, 0x80, 0x3e, 0x80, 0x80, 0x80, 0x3f, 64: 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 65: 0x3c, 0x3d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 66: 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 67: 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 68: 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 69: 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, 70: 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 71: 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 72: 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 73: 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, 74: }; 75: 76: 77: void init_encryption(key_text) 78: char *key_text; 79: { 80: des_cblock key_bin; 81: 82: des_string_to_key(key_text, &key_bin); 83: des_set_key(&key_bin, sched); 84: } 85: 86: char *make_packet(uid, laddr, lport, faddr, fport) 87: int uid; 88: struct in_addr *laddr, *faddr; 89: int lport, fport; 90: { 91: struct timeval tv; 92: union data r; 93: int res, i, j; 94: 95: res = gettimeofday(&tv, NULL); 96: srand(tv.tv_usec); 97: 98: r.fields.random = rand(); 99: r.fields.uid = htons(uid); 100: if (res == 0) 101: { 102: r.fields.date = htonl(tv.tv_sec); 103: } 104: else 105: { 106: r.fields.date = htonl(0); 107: } 108: 109: r.fields.ip_local = laddr->s_addr; 110: r.fields.ip_remote = faddr->s_addr; 111: r.fields.port_local = htons(lport); 112: r.fields.port_remote = htons(fport); 113: 114: r.fields.checksum = 0; 115: for (i = 1; i < 6; i++) 116: { 117: r.longs[0] ^= r.longs[i]; 118: } 119: 120: des_ecb_encrypt((des_cblock *)&(r.longs[0]), (des_cblock *)&(r.longs[0]), 121: sched, DES_ENCRYPT); 122: r.longs[2] ^= r.longs[0]; 123: r.longs[3] ^= r.longs[1]; 124: 125: des_ecb_encrypt((des_cblock *)&(r.longs[2]), (des_cblock *)&(r.longs[2]), 126: sched, DES_ENCRYPT); 127: r.longs[4] ^= r.longs[2]; 128: r.longs[5] ^= r.longs[3]; 129: 130: des_ecb_encrypt((des_cblock *)&(r.longs[4]), (des_cblock *)&(r.longs[4]), 131: sched, DES_ENCRYPT); 132: 133: for (i = 0, j = 0; i < 24; i+=3, j+=4) 134: { 135: result[j ] = to_asc[63 & (r.chars[i ] >> 2)]; 136: result[j+1] = to_asc[63 & ((r.chars[i ] << 4) + (r.chars[i+1] >> 4))]; 137: result[j+2] = to_asc[63 & ((r.chars[i+1] << 2) + (r.chars[i+2] >> 6))]; 138: result[j+3] = to_asc[63 & (r.chars[i+2])]; 139: } 140: result[32] = '\0'; 141: 142: return result; 143: } 144: 145: #define MAX_KEYS 1024 146: 147: static des_cblock keys[MAX_KEYS]; 148: static int num_keys; 149: 150: void init_decryption(key_file) 151: FILE *key_file; 152: { 153: char buf[1024]; 154: 155: num_keys = 0; 156: 157: while (fgets(buf, 1024, key_file) != NULL && num_keys < MAX_KEYS) 158: { 159: des_string_to_key(buf, &keys[num_keys++]); 160: } 161: 162: des_set_key (&keys [0], sched); 163: } 164: 165: 166: static char readable[75]; 167: 168: char *decrypt_packet(packet) 169: char *packet; 170: { 171: union data r; 172: int i, j, k; 173: time_t date_in_sec; 174: char *date_in_ascii; 175: 176: for (k = -1; k < num_keys; k++) 177: { 178: if (k >= 0) 179: des_set_key(&keys [k], sched); 180: 181: for(i = 0, j = 0; i < 24; i+=3, j+=4) 182: { 183: r.chars[i ] = (to_bin[packet[j ]]<<2)+(to_bin[packet[j+1]]>>4); 184: r.chars[i+1] = (to_bin[packet[j+1]]<<4)+(to_bin[packet[j+2]]>>2); 185: r.chars[i+2] = (to_bin[packet[j+2]] << 6) + (to_bin[packet[j+3]]); 186: } 187: 188: des_ecb_encrypt((des_cblock *)&(r.longs[4]), 189: (des_cblock *)&(r.longs[4]), 190: sched, DES_DECRYPT); 191: r.longs[4] ^= r.longs[2]; 192: r.longs[5] ^= r.longs[3]; 193: 194: des_ecb_encrypt((des_cblock *)&(r.longs[2]), 195: (des_cblock *)&(r.longs[2]), 196: sched, DES_DECRYPT); 197: 198: r.longs[2] ^= r.longs[0]; 199: r.longs[3] ^= r.longs[1]; 200: des_ecb_encrypt((des_cblock *)&(r.longs[0]), 201: (des_cblock *)&(r.longs[0]), 202: sched, DES_DECRYPT); 203: 204: for (i = 1; i < 6; i++) 205: { 206: r.longs[0] ^= r.longs[i]; 207: } 208: 209: if (r.fields.checksum == 0) 210: goto GoodKey; 211: } 212: return NULL; 213: 214: GoodKey: 215: date_in_sec = ntohl(r.fields.date); 216: date_in_ascii = ctime(&date_in_sec); 217: 218: sprintf(readable, "%24.24s %u %u.%u.%u.%u %u %u.%u.%u.%u %u", 219: date_in_ascii, ntohs(r.fields.uid), 220: ((unsigned char *) &r.fields.ip_local)[0], 221: ((unsigned char *) &r.fields.ip_local)[1], 222: ((unsigned char *) &r.fields.ip_local)[2], 223: ((unsigned char *) &r.fields.ip_local)[3], 224: (unsigned) ntohs(r.fields.port_local), 225: ((unsigned char *) &r.fields.ip_remote)[0], 226: ((unsigned char *) &r.fields.ip_remote)[1], 227: ((unsigned char *) &r.fields.ip_remote)[2], 228: ((unsigned char *) &r.fields.ip_remote)[3], 229: (unsigned) ntohs(r.fields.port_remote)); 230: 231: return readable; 232: } 233: 234: #else 235: 236: #ifndef NeXT31 237: int dummy = 0; /* Just here to make some compilers shut up :-) */ 238: #endif 239: 240: #endif