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 334