|
|
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.