1 /* Copyright 2000 Enhanced Software Technologies Inc.
2  *   All Rights Reserved
3  *
4  * Released for public use under a BSD-style license. See file LICENSE
5  * for details.
6  *
7  *   Encrypt a file in CFB-128 mode using AES candidate "twofish".
8  *
9  * Cleaned up a bit in a desperate bid to keep busy in aftermath of
10  * EST's demise.
11 */
12 
13 
14 #include "config.h"
15 
16 #include <stdio.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 
22 #include "rijndael.h"
23 #include "aescmdline.h"
24 #include "bin2hex.h"
25 #include "dstring.h"
26 #include "dorandom.h"
27 
28 static int cfb128_idx=-1;
29 
30 static BYTE *cfb_blk;
31 static BYTE cfb_crypt[16];
32 
cryptblock(char * src,int srclen)33 static void cryptblock(char *src, int srclen) {
34   int i,ch;
35 
36   /* Now to encrypt each individual character in cfb mode: */
37   for (i=0; i<srclen; i++) {
38     if ((cfb128_idx < 0) || (cfb128_idx > 15)) {
39 
40       blockEncrypt(&cipher,&key,cfb_blk,128,cfb_crypt);
41       /*encrypt(cfb_blk,cfb_crypt); */
42 
43       cfb128_idx=0;
44     }
45     /* XOR the data with a byte from our encrypted buffer. */
46     ch=src[i] ^ cfb_crypt[cfb128_idx];
47     /* do output feedback: put crypted byte into next block to be crypted */
48     cfb_blk[cfb128_idx++]=ch;
49     src[i]=(char) ch;
50   }
51 
52   return;
53 }
54 
55 
cryptfile(int infile,int outfile)56 static void cryptfile(int infile,int outfile) {
57   BYTE *salt;
58   int result;
59 
60 #define CRYPTBUF_SIZE 8192
61   char buf[CRYPTBUF_SIZE];
62   int bufsize;  /* how many chars are currently in that buffer. */
63 
64   result=urand_seed(NULL);
65   if (result) {
66     fprintf(stderr,"%s:error:Could not seed PRNG\n",progname);
67     perror(progname);
68     usage();
69   }
70 
71   salt=urand_get(16);
72 
73 
74   if (!salt) {
75     fprintf(stderr,"%s:error:could not get salt from PRNG\n",progname);
76     perror(progname);
77     usage();
78   }
79 
80   /* set the feedback buffer to be the salt. */
81   cfb_blk=salt;
82 
83   /* we have salt... now write it to outfile.... */
84 
85   ewrite(outfile,salt,16);
86 
87 
88   /* Now initialize the cipher: */
89   if (cipherInit(&cipher,MODE_ECB,NULL) != TRUE) {
90     fprintf(stderr,"%s:Could not initialize cipher.\n",progname);
91     usage();
92   }
93 
94   while (bufsize=read(infile,buf,CRYPTBUF_SIZE), bufsize != 0) {
95     if (bufsize<0) { /* some sort of I/O error... */
96       fprintf(stderr,"%s:Error on read.\n",progname);
97       perror(progname);
98       exit(1);
99     }
100     cryptblock(buf,bufsize);
101     ewrite(outfile,buf,bufsize); /* checks for error... */
102   }
103 
104   /* okay, we've done everything... */
105 
106   return;
107 }
108 
main(int argc,char ** argv)109 int main(int argc, char **argv) {
110 
111   char * infile;
112   int keysize, op;
113   size_t len;
114   keysize = 128; /* default to 128 bit keys */
115   progname = argv[0];
116   infile = NULL;
117   while (1) {
118     op = getopt(argc, argv, "k:s:");
119     if (op == -1) break;
120     switch (op) {
121     case 'k': /* keyfile */
122       len = strlen(optarg);
123       if ((infile = (char *)malloc(len + 1)) == NULL) {
124 	fprintf(stderr, "malloc failed.\n");
125 	exit(1);
126       }
127       snprintf(infile, len + 1, "%s", optarg);
128       break;
129     case 's':
130       keysize = atoi(optarg);
131       if ((keysize != 128) && (keysize != 192) & (keysize != 256)) {
132 	fprintf(stderr, "keysize must be one of 128, 192, 256.\n");
133 	exit(1);
134       }
135       break;
136     default:
137       usage();
138       exit(1);
139     }
140   }
141 
142   if (infile == NULL) {usage(); exit(1);}
143   if (!strcmp(infile, "-")) {
144     read_key_from_stdin(fileno(stdin), keysize);
145   } else {
146     read_key(infile, keysize); /* read the keyfile, hopefully! */
147   }
148 
149   cryptfile(fileno(stdin),fileno(stdout));
150 
151 
152   exit(0);
153 
154 }
155