URI:
       tpscrypt.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tpscrypt.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 /*****************************************************************************/