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    decrypt a file in CFB-128 mode using AES Rijndael algorithm.
8 
9 
10 */
11 #include "config.h"
12 
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 
19 #include "aes.h"
20 #include "aescmdline.h"
21 #include "bin2hex.h"
22 #include "dstring.h"
23 
24 static int cfb128_idx=-1;
25 
26 static BYTE cfb_blk[16];
27 static BYTE cfb_crypt[16];
28 
decryptblock(char * src,int srclen)29 static void decryptblock(char *src, int srclen) {
30   int i,ch;
31 
32   /* Now to encrypt each individual character in cfb mode: */
33   for (i=0; i<srclen; i++) {
34     if (cfb128_idx < 0 || cfb128_idx > 15) {
35       blockEncrypt(&cipher,&key,cfb_blk,128,cfb_crypt);
36 
37       /* encrypt(cfb_blk,cfb_crypt); */
38       cfb128_idx=0;
39     }
40     ch=src[i];
41     src[i]=ch ^ cfb_crypt[cfb128_idx];
42     /* do output feedback: put crypted byte into next block to be crypted */
43     cfb_blk[cfb128_idx++]=ch;
44   }
45 
46 }
47 
48 
decryptfile(int infile,int outfile)49 static void decryptfile(int infile,int outfile) {
50   int n, result;
51 
52 #define CRYPTBUF_SIZE 262144
53   char buf[CRYPTBUF_SIZE];
54 
55   int bufsize;  /* how many chars are currently in that buffer. */
56 
57 
58   /* set feedback buffer to salt. */
59   for (n = result = 0; result < 16; result += n) {
60     n = read(infile, cfb_blk + result, 16 - result);
61     if (n <= 0) {
62       fprintf(stderr,"%s:error:could not get salt from input\n",progname);
63       perror(progname);
64       usage();
65     }
66   }
67 
68   /* Now initialize the cipher: */
69   if (cipherInit(&cipher,MODE_ECB,NULL) != TRUE) {
70     fprintf(stderr,"%s:Could not initialize cipher.\n",progname);
71     usage();
72   }
73 
74   while (bufsize=read(infile,buf,CRYPTBUF_SIZE), bufsize != 0) {
75     if (bufsize<0) { /* some sort of I/O error... */
76       fprintf(stderr,"%s:Error on read.\n",progname);
77       perror(progname);
78       exit(1);
79     }
80 
81     decryptblock(buf,bufsize);
82     ewrite(outfile,buf,bufsize); /* checks for error... */
83   }
84 
85   /* okay, we've done everything... */
86 
87   return;
88 }
89 
main(int argc,char ** argv)90 int main(int argc, char **argv) {
91 
92   char * infile;
93   int keysize, op;
94   size_t len;
95 
96   keysize = 128; /* default to 128 bit keys */
97   progname= argv[0];
98   infile = NULL;
99 
100   while (1) {
101     op = getopt(argc, argv, "k:s:");
102     if (op == -1) break;
103     switch (op) {
104     case 'k': /* keyfile */
105       len = strlen(optarg);
106       if ((infile = (char *)malloc(len + 1)) == NULL) {
107         fprintf(stderr, "malloc failed.\n");
108         exit(1);
109       }
110       snprintf(infile, len + 1, "%s", optarg);
111       break;
112     case 's':
113       keysize = atoi(optarg);
114       if ((keysize != 128) && (keysize != 192) & (keysize != 256)) {
115         fprintf(stderr, "keysize must be one of 128, 192, 256.\n");
116         exit(1);
117       }
118       break;
119     default:
120       usage();
121       exit(1);
122     }
123   }
124 
125   if (infile == NULL) { usage(); exit(1);}
126 
127 
128   if (strcmp(infile,"-")==0) {
129     read_key_from_stdin(fileno(stdin), keysize);
130   } else {
131     read_key(infile, keysize); /* read the keyfile, hopefully! */
132   }
133 
134   decryptfile(fileno(stdin),fileno(stdout));
135 
136   exit(0);
137 
138 }
139