1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 
10 /* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */
11 /* File de/encryption, using libtomcrypt */
12 /* Written by Daniel Richards <kyhwana@world-net.co.nz> */
13 /* Help from Tom St Denis with various bits */
14 /* This code is public domain, no rights reserved. */
15 /* Encrypts by default, -d flag enables decryption */
16 /* ie: ./encrypt blowfish story.txt story.ct */
17 /* ./encrypt -d blowfish story.ct story.pt */
18 
19 #include <tomcrypt.h>
20 
usage(char * name)21 int usage(char *name)
22 {
23    int x;
24 
25    printf("Usage encrypt: %s cipher infile outfile\n", name);
26    printf("Usage decrypt: %s -d cipher infile outfile\n", name);
27    printf("Usage test:    %s -t cipher\nCiphers:\n", name);
28    for (x = 0; cipher_descriptor[x].name != NULL; x++) {
29       printf("%s\n",cipher_descriptor[x].name);
30    }
31    exit(1);
32 }
33 
main(int argc,char * argv[])34 int main(int argc, char *argv[])
35 {
36    unsigned char plaintext[512],ciphertext[512];
37    unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE];
38    unsigned char inbuf[512]; /* i/o block size */
39    unsigned long outlen, y, ivsize, x, decrypt;
40    symmetric_CTR ctr;
41    int cipher_idx, hash_idx, ks;
42    char *infile, *outfile, *cipher;
43    prng_state prng;
44    FILE *fdin, *fdout;
45    int err;
46 
47    /* register algs, so they can be printed */
48    register_all_ciphers();
49    register_all_hashes();
50    register_all_prngs();
51 
52    if (argc < 4) {
53       if ((argc > 2) && (!strcmp(argv[1], "-t"))) {
54         cipher  = argv[2];
55         cipher_idx = find_cipher(cipher);
56         if (cipher_idx == -1) {
57           printf("Invalid cipher %s entered on command line.\n", cipher);
58           exit(-1);
59         } /* if */
60         if (cipher_descriptor[cipher_idx].test)
61         {
62           if (cipher_descriptor[cipher_idx].test() != CRYPT_OK)
63           {
64             printf("Error when testing cipher %s.\n", cipher);
65             exit(-1);
66           }
67           else
68           {
69             printf("Testing cipher %s succeeded.\n", cipher);
70             exit(0);
71           } /* if ... else */
72         } /* if */
73       }
74       return usage(argv[0]);
75    }
76 
77    if (!strcmp(argv[1], "-d")) {
78       decrypt = 1;
79       cipher  = argv[2];
80       infile  = argv[3];
81       outfile = argv[4];
82    } else {
83       decrypt = 0;
84       cipher  = argv[1];
85       infile  = argv[2];
86       outfile = argv[3];
87    }
88 
89    /* file handles setup */
90    fdin = fopen(infile,"rb");
91    if (fdin == NULL) {
92       perror("Can't open input for reading");
93       exit(-1);
94    }
95 
96    fdout = fopen(outfile,"wb");
97    if (fdout == NULL) {
98       perror("Can't open output for writing");
99       exit(-1);
100    }
101 
102    cipher_idx = find_cipher(cipher);
103    if (cipher_idx == -1) {
104       printf("Invalid cipher entered on command line.\n");
105       exit(-1);
106    }
107 
108    hash_idx = find_hash("sha256");
109    if (hash_idx == -1) {
110       printf("LTC_SHA256 not found...?\n");
111       exit(-1);
112    }
113 
114    ivsize = cipher_descriptor[cipher_idx].block_length;
115    ks = hash_descriptor[hash_idx].hashsize;
116    if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) {
117       printf("Invalid keysize???\n");
118       exit(-1);
119    }
120 
121    printf("\nEnter key: ");
122    if(fgets((char *)tmpkey,sizeof(tmpkey), stdin) == NULL)
123       exit(-1);
124    outlen = sizeof(key);
125    if ((err = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) {
126       printf("Error hashing key: %s\n", error_to_string(err));
127       exit(-1);
128    }
129 
130    if (decrypt) {
131       /* Need to read in IV */
132       if (fread(IV,1,ivsize,fdin) != ivsize) {
133          printf("Error reading IV from input.\n");
134          exit(-1);
135       }
136 
137       if ((err = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
138          printf("ctr_start error: %s\n",error_to_string(err));
139          exit(-1);
140       }
141 
142       /* IV done */
143       do {
144          y = fread(inbuf,1,sizeof(inbuf),fdin);
145 
146          if ((err = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) {
147             printf("ctr_decrypt error: %s\n", error_to_string(err));
148             exit(-1);
149          }
150 
151          if (fwrite(plaintext,1,y,fdout) != y) {
152             printf("Error writing to file.\n");
153             exit(-1);
154          }
155       } while (y == sizeof(inbuf));
156       fclose(fdin);
157       fclose(fdout);
158 
159    } else {  /* encrypt */
160       /* Setup yarrow for random bytes for IV */
161 
162       if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
163          printf("Error setting up PRNG, %s\n", error_to_string(err));
164       }
165 
166       /* You can use rng_get_bytes on platforms that support it */
167       /* x = rng_get_bytes(IV,ivsize,NULL);*/
168       x = yarrow_read(IV,ivsize,&prng);
169       if (x != ivsize) {
170          printf("Error reading PRNG for IV required.\n");
171          exit(-1);
172       }
173 
174       if (fwrite(IV,1,ivsize,fdout) != ivsize) {
175          printf("Error writing IV to output.\n");
176          exit(-1);
177       }
178 
179       if ((err = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
180          printf("ctr_start error: %s\n",error_to_string(err));
181          exit(-1);
182       }
183 
184       do {
185          y = fread(inbuf,1,sizeof(inbuf),fdin);
186 
187          if ((err = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) {
188             printf("ctr_encrypt error: %s\n", error_to_string(err));
189             exit(-1);
190          }
191 
192          if (fwrite(ciphertext,1,y,fdout) != y) {
193             printf("Error writing to output.\n");
194             exit(-1);
195          }
196       } while (y == sizeof(inbuf));
197       fclose(fdout);
198       fclose(fdin);
199    }
200    return 0;
201 }
202 
203 /* ref:         $Format:%D$ */
204 /* git commit:  $Format:%H$ */
205 /* commit time: $Format:%ai$ */
206