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