|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Phil Karn, derived from original work by Jim Gillogly and ! 7: * Richard Outerbridge. ! 8: * ! 9: * Redistribution and use in source and binary forms are permitted ! 10: * provided that: (1) source distributions retain this entire copyright ! 11: * notice and comment, and (2) distributions including binaries display ! 12: * the following acknowledgement: ``This product includes software ! 13: * developed by the University of California, Berkeley and its contributors'' ! 14: * in the documentation or other materials provided with the distribution ! 15: * and in all advertising materials mentioning features or use of this ! 16: * software. Neither the name of the University nor the names of its ! 17: * contributors may be used to endorse or promote products derived ! 18: * from this software without specific prior written permission. ! 19: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 20: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 21: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 22: */ ! 23: ! 24: #ifndef lint ! 25: char copyright[] = ! 26: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 27: All rights reserved.\n"; ! 28: #endif /* not lint */ ! 29: ! 30: #ifndef lint ! 31: static char sccsid[] = "@(#)main.c 5.3 (Berkeley) 6/1/90"; ! 32: #endif /* not lint */ ! 33: ! 34: /* Encrypt/decrypt command compatible with Sun's "des" command */ ! 35: #include <stdio.h> ! 36: ! 37: char iv[8]; /* Initial vector for CBC mode */ ! 38: int block; ! 39: ! 40: main(argc,argv) ! 41: int argc; ! 42: char *argv[]; ! 43: { ! 44: int c,cnt,encrypt,decrypt,hexflag; ! 45: register int i; ! 46: char key[8],tkey1[20],tkey2[20],*akey,*getpass(); ! 47: extern char *optarg; ! 48: ! 49: hexflag = block = encrypt = decrypt = 0; ! 50: akey = NULL; ! 51: while((c = getopt(argc,argv,"hedk:b")) != EOF){ ! 52: switch(c){ ! 53: case 'h': ! 54: hexflag++; ! 55: break; ! 56: case 'e': ! 57: encrypt++; ! 58: break; ! 59: case 'd': ! 60: decrypt++; ! 61: break; ! 62: case 'k': ! 63: akey = optarg; ! 64: break; ! 65: case 'b': ! 66: block++; ! 67: break; ! 68: } ! 69: } ! 70: if(encrypt == 0 && decrypt == 0){ ! 71: fprintf(stderr,"Usage: des -e|-d [-h] [-k key]\n"); ! 72: exit(2); ! 73: } ! 74: if(akey == NULL){ ! 75: /* No key on command line, prompt for it */ ! 76: memset(tkey1,0,sizeof(tkey1)); ! 77: memset(tkey2,0,sizeof(tkey2)); ! 78: for(;;){ ! 79: akey = getpass("Enter key: "); ! 80: strncpy(tkey1,akey,sizeof(tkey1)); ! 81: akey = getpass("Enter key again: "); ! 82: strncpy(tkey2,akey,sizeof(tkey2)); ! 83: if(strncmp(tkey1,tkey2,sizeof(tkey1)) != 0){ ! 84: fprintf(stderr,"Key mistyped, try again\n"); ! 85: } else ! 86: break; ! 87: } ! 88: akey = tkey1; ! 89: } ! 90: if(hexflag){ ! 91: for(i=0;i<16;i++){ ! 92: if(htoa(akey[i]) == -1){ ! 93: fprintf(stderr,"Non-hex character in key\n"); ! 94: exit(1); ! 95: } ! 96: } ! 97: gethex(key,akey,8); ! 98: } else { ! 99: strncpy(key,akey,8); ! 100: /* Set up key, determine parity bit */ ! 101: for(cnt = 0; cnt < 8; cnt++){ ! 102: c = 0; ! 103: for(i=0;i<7;i++) ! 104: if(key[cnt] & (1 << i)) ! 105: c++; ! 106: if((c & 1) == 0) ! 107: key[cnt] |= 0x80; ! 108: else ! 109: key[cnt] &= ~0x80; ! 110: } ! 111: } ! 112: /* Blot out original key */ ! 113: i = strlen(akey); ! 114: i = (i < 8) ? i : 8; ! 115: memset(akey,0,i); ! 116: ! 117: desinit(0); ! 118: setkey(key); ! 119: ! 120: /* Initialize IV to all zeros */ ! 121: memset(iv,0,8); ! 122: ! 123: if(encrypt){ ! 124: doencrypt(); ! 125: } else { ! 126: dodecrypt(); ! 127: } ! 128: } ! 129: /* Encrypt standard input to standard output */ ! 130: doencrypt() ! 131: { ! 132: char work[8],*cp,*cp1; ! 133: int cnt,i; ! 134: ! 135: for(;;){ ! 136: if((cnt = fread(work,1,8,stdin)) != 8){ ! 137: /* Put residual byte count in the last block. ! 138: * Note that garbage is left in the other bytes, ! 139: * if any; this is a feature, not a bug, since it'll ! 140: * be stripped out at decrypt time. ! 141: */ ! 142: work[7] = cnt; ! 143: } ! 144: if(!block){ ! 145: /* CBC mode; chain in last cipher word */ ! 146: cp = work; ! 147: cp1 = iv; ! 148: for(i=8; i!=0; i--) ! 149: *cp++ ^= *cp1++; ! 150: } ! 151: endes(work); /* Encrypt block */ ! 152: if(!block){ /* Save outgoing ciphertext for chain */ ! 153: memcpy(iv,work,8); ! 154: } ! 155: fwrite(work,1,8,stdout); ! 156: if(cnt != 8) ! 157: break; ! 158: } ! 159: } ! 160: dodecrypt() ! 161: { ! 162: char work[8],nwork[8],ivtmp[8],*cp,*cp1; ! 163: int cnt,i; ! 164: ! 165: ! 166: cnt = fread(work,1,8,stdin); /* Prime the pump */ ! 167: for(;;){ ! 168: if(!block){ /* Save incoming ciphertext for chain */ ! 169: memcpy(ivtmp,work,8); ! 170: } ! 171: dedes(work); ! 172: if(!block){ /* Unchain block, save ciphertext for next */ ! 173: cp = work; ! 174: cp1 = iv; ! 175: for(i=8; i!=0; i--){ ! 176: *cp++ ^= *cp1++; ! 177: } ! 178: memcpy(iv,ivtmp,8); ! 179: } ! 180: /* Save buffer pending next read */ ! 181: memcpy(nwork,work,8); ! 182: /* Try to read next block */ ! 183: cnt = fread(work,1,8,stdin); ! 184: if(cnt != 8){ /* Can "only" be 0 if not 8 */ ! 185: /* Prev block was last one, write appropriate number ! 186: * of bytes ! 187: */ ! 188: cnt = nwork[7]; ! 189: if(cnt < 0 || cnt > 7){ ! 190: fprintf(stderr,"Corrupted file or wrong key\n"); ! 191: } else if(cnt != 0) ! 192: fwrite(nwork,1,cnt,stdout); ! 193: exit(0); ! 194: } else { ! 195: /* Now okay to write previous buffer */ ! 196: fwrite(nwork,1,8,stdout); ! 197: } ! 198: ! 199: } ! 200: } ! 201: /* Convert hex/ascii nybble to binary */ ! 202: int ! 203: htoa(c) ! 204: char c; ! 205: { ! 206: if(c >= '0' && c <= '9') ! 207: return c - '0'; ! 208: if(c >= 'a' && c <= 'f') ! 209: return 10 + c - 'a'; ! 210: if(c >= 'A' && c <= 'F') ! 211: return 10 + c - 'A'; ! 212: return -1; ! 213: } ! 214: /* Convert bytes from hex/ascii to binary */ ! 215: gethex(result,cp,cnt) ! 216: register char *result; ! 217: register char *cp; ! 218: register int cnt; ! 219: { ! 220: while(cnt-- != 0){ ! 221: *result = htoa(*cp++) << 4; ! 222: *result++ |= htoa(*cp++); ! 223: } ! 224: } ! 225: #ifdef DEBUG ! 226: put8(cp) ! 227: register char *cp; ! 228: { ! 229: int i; ! 230: ! 231: for(i=0;i<8;i++){ ! 232: fprintf(stderr,"%02x ",*cp++ & 0xff); ! 233: } ! 234: } ! 235: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.