plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

pscrypt.c (6547B)


      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;
     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     fp_in = stdin;
     78 
     79     options();
     80     initialize();
     81     arguments();
     82 
     83     exit(0);
     84 
     85 }   /* End of main */
     86 
     87 /*****************************************************************************/
     88 
     89 options()
     90 
     91 {
     92 
     93     int		ch;
     94     char	*names = "bde:l:os:xBSX";
     95 
     96     extern char	*optarg;
     97     extern int	optind;
     98 
     99 /*
    100  *
    101  * Command line options.
    102  *
    103  */
    104 
    105     while ( (ch = getopt(argc, argv, names)) != EOF )
    106 	switch ( ch ) {
    107 	    case 'b':			/* binary input */
    108 		    input = BINARY;
    109 		    break;
    110 
    111 	    case 'd':			/* decrypt */
    112 		    mode = DECRYPT;
    113 		    break;
    114 
    115 	    case 'e':			/* encrypt */
    116 		    mode = ENCRYPT;
    117 		    if ( *optarg == '0' && *optarg == 'x' )
    118 			optarg += 2;
    119 		    sscanf(optarg, "%8x", &cryptkey);
    120 		    break;
    121 
    122 	    case 'l':			/* line length hex output */
    123 		    linelength = atoi(optarg);
    124 		    break;
    125 
    126 	    case 'o':			/* output all bytes - debugging */
    127 		    outoffset = 0;
    128 		    break;
    129 
    130 	    case 's':			/* seed */
    131 		    if ( *optarg == 'e' )
    132 			seed = EEXEC;
    133 		    else if ( *optarg == 's' )
    134 			seed = CHARSTRING;
    135 		    else if ( *optarg == '0' && *(optarg+1) == 'x' )
    136 			sscanf(optarg+2, "%x", &seed);
    137 		    else if ( *optarg == '0' )
    138 			sscanf(optarg, "%o", &seed);
    139 		    else sscanf(optarg, "%d", &seed);
    140 		    break;
    141 
    142 	    case 'x':			/* hex input */
    143 		    input = HEX;
    144 		    break;
    145 
    146 	    case 'B':			/* binary output */
    147 		    output = BINARY;
    148 		    break;
    149 
    150 	    case 'X':			/* hex output */
    151 		    output = HEX;
    152 		    break;
    153 
    154 	    case '?':			/* don't understand the option */
    155 		    fprintf(stderr, "bad option -%c\n", ch);
    156 		    exit(1);
    157 		    break;
    158 
    159 	    default:			/* don't know what to do for ch */
    160 		    fprintf(stderr, "missing case for option -%c\n", ch);
    161 		    exit(1);
    162 		    break;
    163 	}   /* End switch */
    164 
    165     argc -= optind;			/* get ready for non-option args */
    166     argv += optind;
    167 
    168 }   /* End of options */
    169 
    170 /*****************************************************************************/
    171 
    172 initialize()
    173 
    174 {
    175 
    176 /*
    177  *
    178  * Initialization that has to be done after the options.
    179  *
    180  */
    181 
    182     key = seed;
    183 
    184     if ( mode == DECRYPT ) {
    185 	input = (input == NOTSET) ? HEX : input;
    186 	output = (output == NOTSET) ? BINARY : output;
    187 	inoffset = (inoffset == NOTSET) ? 0 : inoffset;
    188 	outoffset = (outoffset == NOTSET) ? -4 : outoffset;
    189     } else {
    190 	input = (input == NOTSET) ? BINARY : input;
    191 	output = (output == NOTSET) ? HEX : output;
    192 	inoffset = (inoffset == NOTSET) ? 4 : inoffset;
    193 	outoffset = (outoffset == NOTSET) ? 0 : outoffset;
    194     }	/* End else */
    195 
    196     if ( linelength <= 0 )
    197 	linelength = LINELENGTH;
    198 
    199 }   /* End of initialize */
    200 
    201 /*****************************************************************************/
    202 
    203 arguments()
    204 
    205 {
    206 
    207 /*
    208  *
    209  * Everything left is an input file. No arguments or '-' means stdin.
    210  *
    211  */
    212 
    213     if ( argc < 1 )
    214 	crypt();
    215     else
    216 	while ( argc > 0 ) {
    217 	    if ( strcmp(*argv, "-") == 0 )
    218 		fp_in = stdin;
    219 	    else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
    220 		fprintf(stderr, "can't open %s\n", *argv);
    221 		exit(1);
    222 	    }	/* End if */
    223 	    crypt();
    224 	    if ( fp_in != stdin )
    225 		fclose(fp_in);
    226 	    argc--;
    227 	    argv++;
    228 	}   /* End while */
    229 
    230 }   /* End of arguments */
    231 
    232 /*****************************************************************************/
    233 
    234 crypt()
    235 
    236 {
    237 
    238     unsigned int	cypher;
    239     unsigned int	clear;
    240 
    241 /*
    242  *
    243  * Runs the encryption/decryption algorithm.
    244  *
    245  */
    246 
    247     while ( lastchar != EOF ) {
    248 	cypher = nextbyte();
    249 	clear = ((key >> 8) ^ cypher) & 0xFF;
    250 	key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
    251 	if ( ++outoffset > 0 && lastchar != EOF ) {
    252 	    if ( output == HEX ) {
    253 		printf("%.2X", clear);
    254 		if ( linelength > 0 && (outoffset % linelength) == 0 )
    255 		    putchar('\n');
    256 	    } else putchar(clear);
    257 	}   /* End if */
    258     }	/* End while */
    259 
    260 }   /* End of crypt */
    261 
    262 /*****************************************************************************/
    263 
    264 nextbyte()
    265 
    266 {
    267 
    268     int		val = EOF;
    269 
    270 /*
    271  *
    272  * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
    273  * positive, otherwise reads (hex or binary) from fp_in.
    274  *
    275  */
    276 
    277     if ( inoffset-- > 0 )
    278 	val = (cryptkey >> (inoffset*8)) & 0xFF;
    279     else if ( input == HEX ) {
    280 	if ( (val = nexthexchar()) != EOF )
    281 	    val = (val << 4) | nexthexchar();
    282     } else if ( input == BINARY )
    283 	val = Getc(fp_in);
    284 
    285     return(val);
    286 
    287 }   /* End of nextbyte */
    288 
    289 /*****************************************************************************/
    290 
    291 nexthexchar()
    292 
    293 {
    294 
    295     int		ch;
    296 
    297 /*
    298  *
    299  * Reads the next hex character.
    300  *
    301  */
    302 
    303     while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
    304 
    305     if ( isdigit(ch) )
    306 	ch -= '0';
    307     else if ( isupper(ch) )
    308 	ch -= 'A' - 10;
    309     else if ( islower(ch) )
    310 	ch -= 'a' - 10;
    311 
    312     return(ch);
    313 
    314 }   /* End of nexthexchar */
    315 
    316 /*****************************************************************************/
    317 
    318 Getc(fp)
    319 
    320     FILE	*fp;
    321 
    322 {
    323 
    324 /*
    325  *
    326  * Reads the next byte from *fp, sets lastchar, and returns the character.
    327  *
    328  */
    329 
    330     return(lastchar = getc(fp));
    331 
    332 }   /* End of Getc */
    333 
    334 /*****************************************************************************/