1 /* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */ 2 /* File de/encryption, using libtomcrypt */ 3 /* Written by Daniel Richards <kyhwana (at) world-net.co.nz> */ 4 /* Help from Tom St Denis with various bits */ 5 /* This code is public domain, no rights reserved. */ 6 /* Encrypts by default, -d flag enables decryption */ 7 /* ie: ./encrypt blowfish story.txt story.ct */ 8 /* ./encrypt -d blowfish story.ct story.pt */ 9 10 #include <tomcrypt.h> 11 12 int errno; 13 14 int usage(char *name) 15 { 16 int x; 17 18 printf("Usage: %s [-d](ecrypt) cipher infile outfile\nCiphers:\n", name); 19 for (x = 0; cipher_descriptor[x].name != NULL; x++) { 20 printf("%s\n",cipher_descriptor[x].name); 21 } 22 exit(1); 23 } 24 25 void register_algs(void) 26 { 27 int x; 28 29 #ifdef RIJNDAEL 30 register_cipher (&aes_desc); 31 #endif 32 #ifdef BLOWFISH 33 register_cipher (&blowfish_desc); 34 #endif 35 #ifdef XTEA 36 register_cipher (&xtea_desc); 37 #endif 38 #ifdef RC5 39 register_cipher (&rc5_desc); 40 #endif 41 #ifdef RC6 42 register_cipher (&rc6_desc); 43 #endif 44 #ifdef SAFERP 45 register_cipher (&saferp_desc); 46 #endif 47 #ifdef TWOFISH 48 register_cipher (&twofish_desc); 49 #endif 50 #ifdef SAFER 51 register_cipher (&safer_k64_desc); 52 register_cipher (&safer_sk64_desc); 53 register_cipher (&safer_k128_desc); 54 register_cipher (&safer_sk128_desc); 55 #endif 56 #ifdef RC2 57 register_cipher (&rc2_desc); 58 #endif 59 #ifdef DES 60 register_cipher (&des_desc); 61 register_cipher (&des3_desc); 62 #endif 63 #ifdef CAST5 64 register_cipher (&cast5_desc); 65 #endif 66 #ifdef NOEKEON 67 register_cipher (&noekeon_desc); 68 #endif 69 #ifdef SKIPJACK 70 register_cipher (&skipjack_desc); 71 #endif 72 #ifdef KHAZAD 73 register_cipher (&khazad_desc); 74 #endif 75 #ifdef ANUBIS 76 register_cipher (&anubis_desc); 77 #endif 78 79 if (register_hash(&sha256_desc) == -1) { 80 printf("Error registering SHA256\n"); 81 exit(-1); 82 } 83 84 if (register_prng(&yarrow_desc) == -1) { 85 printf("Error registering yarrow PRNG\n"); 86 exit(-1); 87 } 88 89 if (register_prng(&sprng_desc) == -1) { 90 printf("Error registering sprng PRNG\n"); 91 exit(-1); 92 } 93 } 94 95 int main(int argc, char *argv[]) 96 { 97 unsigned char plaintext[512],ciphertext[512]; 98 unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; 99 unsigned char inbuf[512]; /* i/o block size */ 100 unsigned long outlen, y, ivsize, x, decrypt; 101 symmetric_CTR ctr; 102 int cipher_idx, hash_idx, ks; 103 char *infile, *outfile, *cipher; 104 prng_state prng; 105 FILE *fdin, *fdout; 106 107 /* register algs, so they can be printed */ 108 register_algs(); 109 110 if (argc < 4) { 111 return usage(argv[0]); 112 } 113 114 if (!strcmp(argv[1], "-d")) { 115 decrypt = 1; 116 cipher = argv[2]; 117 infile = argv[3]; 118 outfile = argv[4]; 119 } else { 120 decrypt = 0; 121 cipher = argv[1]; 122 infile = argv[2]; 123 outfile = argv[3]; 124 } 125 126 /* file handles setup */ 127 fdin = fopen(infile,"rb"); 128 if (fdin == NULL) { 129 perror("Can't open input for reading"); 130 exit(-1); 131 } 132 133 fdout = fopen(outfile,"wb"); 134 if (fdout == NULL) { 135 perror("Can't open output for writing"); 136 exit(-1); 137 } 138 139 cipher_idx = find_cipher(cipher); 140 if (cipher_idx == -1) { 141 printf("Invalid cipher entered on command line.\n"); 142 exit(-1); 143 } 144 145 hash_idx = find_hash("sha256"); 146 if (hash_idx == -1) { 147 printf("SHA256 not found...?\n"); 148 exit(-1); 149 } 150 151 ivsize = cipher_descriptor[cipher_idx].block_length; 152 ks = hash_descriptor[hash_idx].hashsize; 153 if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { 154 printf("Invalid keysize???\n"); 155 exit(-1); 156 } 157 158 printf("\nEnter key: "); 159 fgets((char *)tmpkey,sizeof(tmpkey), stdin); 160 outlen = sizeof(key); 161 if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { 162 printf("Error hashing key: %s\n", error_to_string(errno)); 163 exit(-1); 164 } 165 166 if (decrypt) { 167 /* Need to read in IV */ 168 if (fread(IV,1,ivsize,fdin) != ivsize) { 169 printf("Error reading IV from input.\n"); 170 exit(-1); 171 } 172 173 if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { 174 printf("ctr_start error: %s\n",error_to_string(errno)); 175 exit(-1); 176 } 177 178 /* IV done */ 179 do { 180 y = fread(inbuf,1,sizeof(inbuf),fdin); 181 182 if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { 183 printf("ctr_decrypt error: %s\n", error_to_string(errno)); 184 exit(-1); 185 } 186 187 if (fwrite(plaintext,1,y,fdout) != y) { 188 printf("Error writing to file.\n"); 189 exit(-1); 190 } 191 } while (y == sizeof(inbuf)); 192 fclose(fdin); 193 fclose(fdout); 194 195 } else { /* encrypt */ 196 /* Setup yarrow for random bytes for IV */ 197 198 if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { 199 printf("Error setting up PRNG, %s\n", error_to_string(errno)); 200 } 201 202 /* You can use rng_get_bytes on platforms that support it */ 203 /* x = rng_get_bytes(IV,ivsize,NULL);*/ 204 x = yarrow_read(IV,ivsize,&prng); 205 if (x != ivsize) { 206 printf("Error reading PRNG for IV required.\n"); 207 exit(-1); 208 } 209 210 if (fwrite(IV,1,ivsize,fdout) != ivsize) { 211 printf("Error writing IV to output.\n"); 212 exit(-1); 213 } 214 215 if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { 216 printf("ctr_start error: %s\n",error_to_string(errno)); 217 exit(-1); 218 } 219 220 do { 221 y = fread(inbuf,1,sizeof(inbuf),fdin); 222 223 if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) { 224 printf("ctr_encrypt error: %s\n", error_to_string(errno)); 225 exit(-1); 226 } 227 228 if (fwrite(ciphertext,1,y,fdout) != y) { 229 printf("Error writing to output.\n"); 230 exit(-1); 231 } 232 } while (y == sizeof(inbuf)); 233 fclose(fdout); 234 fclose(fdin); 235 } 236 return 0; 237 } 238 239 /* $Source: /cvs/libtom/libtomcrypt/demos/encrypt.c,v $ */ 240 /* $Revision: 1.3 $ */ 241 /* $Date: 2005/08/04 20:43:50 $ */ 242