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