Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 *
3
 * Adobe's encryption/decryption algorithm for eexec and show. Runs in
4
 * eexec mode unless told otherwise. Use,
5
 *
6
 *		pscrypt file.cypher > file.clear
7
 *
8
 * to decrypt eexec input. Assumes file.cypher is hex with the key as the
9
 * first four bytes, and writes file.clear as binary (omitting the key).
10
 * Use
11
 *
12
 *		pscrypt -e12ab34ef file.clear >file.cypher
13
 *
14
 * to encrypt file.clear (for eexec) using 12ab34ef as the key. Input is
15
 * binary and output is hex. The key must be given as a hex number. Use
16
 * -sshow to encrypt or decrypt a CharString or Subr,
17
 *
18
 *		pscrypt -sshow file.cypher > file.clear
19
 *
20
 * Use -b or -x to read binary or hex input, and -B or -X to output binary
21
 * or hex.
22
 *
23
 */
24
 
25
#include <stdio.h>
26
#include <ctype.h>
27
 
28
#define ENCRYPT		0
29
#define DECRYPT		1
30
 
31
#define NOTSET		-1
32
#define BINARY		0
33
#define HEX		1
34
#define LINELENGTH	40
35
 
36
#define CHARSTRING	4330
37
#define EEXEC		55665
38
#define MAGIC1		52845
39
#define MAGIC2		22719
40
 
41
int	argc;
42
char	**argv;
43
 
44
int	mode = DECRYPT;
45
int	input = NOTSET;
46
int	output = NOTSET;
47
int	outoffset = NOTSET;
48
int	inoffset = NOTSET;
49
 
50
int	cryptkey = 0;			/* encryption key set with -e */
51
int	linelength = LINELENGTH;	/* only for hex output */
52
int	lastchar = 0;
53
 
54
unsigned long	seed = EEXEC;
55
unsigned long	key;
56
 
57
FILE	*fp_in = stdin;
58
 
59
/*****************************************************************************/
60
 
61
main(agc, agv)
62
 
63
    int		agc;
64
    char	*agv[];
65
 
66
{
67
 
68
/*
69
 *
70
 * Implementation of the encryption/decryption used by eexec and show.
71
 *
72
 */
73
 
74
    argc = agc;
75
    argv = agv;
76
 
77
    options();
78
    initialize();
79
    arguments();
80
 
81
    exit(0);
82
 
83
}   /* End of main */
84
 
85
/*****************************************************************************/
86
 
87
options()
88
 
89
{
90
 
91
    int		ch;
92
    char	*names = "bde:l:os:xBSX";
93
 
94
    extern char	*optarg;
95
    extern int	optind;
96
 
97
/*
98
 *
99
 * Command line options.
100
 *
101
 */
102
 
103
    while ( (ch = getopt(argc, argv, names)) != EOF )
104
	switch ( ch ) {
105
	    case 'b':			/* binary input */
106
		    input = BINARY;
107
		    break;
108
 
109
	    case 'd':			/* decrypt */
110
		    mode = DECRYPT;
111
		    break;
112
 
113
	    case 'e':			/* encrypt */
114
		    mode = ENCRYPT;
115
		    if ( *optarg == '0' && *optarg == 'x' )
116
			optarg += 2;
117
		    sscanf(optarg, "%8x", &cryptkey);
118
		    break;
119
 
120
	    case 'l':			/* line length hex output */
121
		    linelength = atoi(optarg);
122
		    break;
123
 
124
	    case 'o':			/* output all bytes - debugging */
125
		    outoffset = 0;
126
		    break;
127
 
128
	    case 's':			/* seed */
129
		    if ( *optarg == 'e' )
130
			seed = EEXEC;
131
		    else if ( *optarg == 's' )
132
			seed = CHARSTRING;
133
		    else if ( *optarg == '0' && *(optarg+1) == 'x' )
134
			sscanf(optarg+2, "%x", &seed);
135
		    else if ( *optarg == '0' )
136
			sscanf(optarg, "%o", &seed);
137
		    else sscanf(optarg, "%d", &seed);
138
		    break;
139
 
140
	    case 'x':			/* hex input */
141
		    input = HEX;
142
		    break;
143
 
144
	    case 'B':			/* binary output */
145
		    output = BINARY;
146
		    break;
147
 
148
	    case 'X':			/* hex output */
149
		    output = HEX;
150
		    break;
151
 
152
	    case '?':			/* don't understand the option */
153
		    fprintf(stderr, "bad option -%c\n", ch);
154
		    exit(1);
155
		    break;
156
 
157
	    default:			/* don't know what to do for ch */
158
		    fprintf(stderr, "missing case for option -%c\n", ch);
159
		    exit(1);
160
		    break;
161
	}   /* End switch */
162
 
163
    argc -= optind;			/* get ready for non-option args */
164
    argv += optind;
165
 
166
}   /* End of options */
167
 
168
/*****************************************************************************/
169
 
170
initialize()
171
 
172
{
173
 
174
/*
175
 *
176
 * Initialization that has to be done after the options.
177
 *
178
 */
179
 
180
    key = seed;
181
 
182
    if ( mode == DECRYPT ) {
183
	input = (input == NOTSET) ? HEX : input;
184
	output = (output == NOTSET) ? BINARY : output;
185
	inoffset = (inoffset == NOTSET) ? 0 : inoffset;
186
	outoffset = (outoffset == NOTSET) ? -4 : outoffset;
187
    } else {
188
	input = (input == NOTSET) ? BINARY : input;
189
	output = (output == NOTSET) ? HEX : output;
190
	inoffset = (inoffset == NOTSET) ? 4 : inoffset;
191
	outoffset = (outoffset == NOTSET) ? 0 : outoffset;
192
    }	/* End else */
193
 
194
    if ( linelength <= 0 )
195
	linelength = LINELENGTH;
196
 
197
}   /* End of initialize */
198
 
199
/*****************************************************************************/
200
 
201
arguments()
202
 
203
{
204
 
205
/*
206
 *
207
 * Everything left is an input file. No arguments or '-' means stdin.
208
 *
209
 */
210
 
211
    if ( argc < 1 )
212
	crypt();
213
    else
214
	while ( argc > 0 ) {
215
	    if ( strcmp(*argv, "-") == 0 )
216
		fp_in = stdin;
217
	    else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
218
		fprintf(stderr, "can't open %s\n", *argv);
219
		exit(1);
220
	    }	/* End if */
221
	    crypt();
222
	    if ( fp_in != stdin )
223
		fclose(fp_in);
224
	    argc--;
225
	    argv++;
226
	}   /* End while */
227
 
228
}   /* End of arguments */
229
 
230
/*****************************************************************************/
231
 
232
crypt()
233
 
234
{
235
 
236
    unsigned int	cypher;
237
    unsigned int	clear;
238
 
239
/*
240
 *
241
 * Runs the encryption/decryption algorithm.
242
 *
243
 */
244
 
245
    while ( lastchar != EOF ) {
246
	cypher = nextbyte();
247
	clear = ((key >> 8) ^ cypher) & 0xFF;
248
	key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
249
	if ( ++outoffset > 0 && lastchar != EOF ) {
250
	    if ( output == HEX ) {
251
		printf("%.2X", clear);
252
		if ( linelength > 0 && (outoffset % linelength) == 0 )
253
		    putchar('\n');
254
	    } else putchar(clear);
255
	}   /* End if */
256
    }	/* End while */
257
 
258
}   /* End of crypt */
259
 
260
/*****************************************************************************/
261
 
262
nextbyte()
263
 
264
{
265
 
266
    int		val = EOF;
267
 
268
/*
269
 *
270
 * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
271
 * positive, otherwise reads (hex or binary) from fp_in.
272
 *
273
 */
274
 
275
    if ( inoffset-- > 0 )
276
	val = (cryptkey >> (inoffset*8)) & 0xFF;
277
    else if ( input == HEX ) {
278
	if ( (val = nexthexchar()) != EOF )
279
	    val = (val << 4) | nexthexchar();
280
    } else if ( input == BINARY )
281
	val = Getc(fp_in);
282
 
283
    return(val);
284
 
285
}   /* End of nextbyte */
286
 
287
/*****************************************************************************/
288
 
289
nexthexchar()
290
 
291
{
292
 
293
    int		ch;
294
 
295
/*
296
 *
297
 * Reads the next hex character.
298
 *
299
 */
300
 
301
    while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
302
 
303
    if ( isdigit(ch) )
304
	ch -= '0';
305
    else if ( isupper(ch) )
306
	ch -= 'A' - 10;
307
    else if ( islower(ch) )
308
	ch -= 'a' - 10;
309
 
310
    return(ch);
311
 
312
}   /* End of nexthexchar */
313
 
314
/*****************************************************************************/
315
 
316
Getc(fp)
317
 
318
    FILE	*fp;
319
 
320
{
321
 
322
/*
323
 *
324
 * Reads the next byte from *fp, sets lastchar, and returns the character.
325
 *
326
 */
327
 
328
    return(lastchar = getc(fp));
329
 
330
}   /* End of Getc */
331
 
332
/*****************************************************************************/
333