1  /* CodVgn.c - 2012-01-22 */
  2  
  3  /*
  4  CodVgn v1.1 - Encrypts and decrypts a binary file with the Vigenere cipher.
  5  Usage: CodVgn.exe [filename.ext[.cod]] ["key"]
  6  
  7  Update:
  8    http://myc01.free.fr/codvgn/
  9  
 10  License:
 11    Public Domain Dedication (CC0 1.0)
 12    http://creativecommons.org/publicdomain/zero/1.0/
 13  
 14  Changelog:
 15  * CodVgn v1.1 - 2012-01-22 :
 16    - Encryption key with 2400 digits of PI.
 17  * CodVgn v1.0 - 2012-01-21 :
 18    - Cipher with a simple key.
 19  */
 20  
 21  #include <windows.h>
 22  #include <stdio.h>
 23  #include <stdlib.h>
 24  #include <string.h>
 25  #include <sys\stat.h>
 26  #include <fcntl.h>
 27  
 28  #define APP_NAME    "CodVgn v1.1"
 29  #define APP_EXE     "CodVgn.exe"
 30  
 31  #define ENABLE_CRYPT_KEY
 32  
 33  #ifdef ENABLE_CRYPT_KEY
 34  #define MAX_KEY     2400
 35  #else
 36  #define MAX_KEY     64
 37  #endif  // ENABLE_CRYPT_KEY
 38  
 39  #define MAX_BUF     65536
 40  #define CODE        -1
 41  #define DECODE      -2
 42  #define EXT_CODE    ".cod"
 43  
 44  #define ERROR_OK    0
 45  #define ERROR_ARG   1
 46  #define ERROR_KEY   2
 47  #define ERROR_FILE  3
 48  
 49  typedef enum
 50  {
 51      BLACK,
 52      BLUE,
 53      GREEN,
 54      CYAN,
 55      RED,
 56      MAGENTA,
 57      BROWN,
 58      LIGHTGRAY,
 59      DARKGRAY,
 60      LIGHTBLUE,
 61      LIGHTGREEN,
 62      LIGHTCYAN,
 63      LIGHTRED,
 64      LIGHTMAGENTA,
 65      YELLOW,
 66      WHITE
 67  } COLORS;
 68  
 69  int __BACKGROUND = BLACK;
 70  int __FOREGROUND = LIGHTGRAY;
 71  
 72  UCHAR key[MAX_KEY + 1], buffer[MAX_BUF];
 73  int fe = -1, fs = -1;
 74  
 75  void  settextcolor (const int color);
 76  int   gettextcolor (void);
 77  int   getstring    (char *chaine, const int size);
 78  long  codefile     (const long nbuf, long nkey, const long lenkey);
 79  long  decodefile   (const long nbuf, long nkey, const long lenkey);
 80  void  closeexit    (const char *message, const int result);
 81  
 82  #ifdef ENABLE_CRYPT_KEY
 83  // The famous program by Dik T Winter of cwi institute of Holland.
 84  // original: http://www.pi314.net/programmes/tiny.c
 85  #define SCALE   10000
 86  void initpi (char *buf, int digit)
 87  {
 88      int b = 0, c = (digit *= 3.5), d, e = 0, g, p = 0, *f = malloc ((digit + 1) * sizeof (*f));
 89      for (; b - c;) f[b++] = SCALE / 5;
 90      for (; c > 0; c -= 14, _snprintf (&buf[p], 4, "%04d", e + d / SCALE), p += 4, e = d % SCALE)
 91          for (b = c, d = 0, g = c * 2; d += f[b] * SCALE, f[b] = d % --g, d /= g--, --b; d *= b);
 92      free (f);
 93      //buf[p++] = '\0'; puts (buf);
 94  }  // initpi
 95  #endif  // ENABLE_CRYPT_KEY
 96  
 97  
 98  int gettextcolor (void)
 99  {
100      CONSOLE_SCREEN_BUFFER_INFO info;
101  
102      GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
103      __BACKGROUND = info.wAttributes >> 4;
104      __FOREGROUND = info.wAttributes & 0x0F;
105  
106      return info.wAttributes;
107  }  // gettextcolor
108  
109  
110  void settextcolor (const int color)
111  {
112      __FOREGROUND = color;
113      SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE),
114                               color + (__BACKGROUND << 4) );
115  }  // settextcolor
116  
117  
118  long codefile (const long nbuf, long nkey, const long lenkey)
119  {
120      long i;
121      for (i = 0; i < nbuf; i++)
122      {
123          buffer[i] = (key[nkey] + buffer[i]) % 256;
124          if ( (nkey + 1) > lenkey)
125              nkey = 0;
126          else
127              nkey++;
128      }
129      return nkey;
130  }  // codefile
131  
132  
133  long decodefile (const long nbuf, long nkey, const long lenkey)
134  {
135      long d, i;
136      for (i = 0; i < nbuf; i++)
137      {
138          if ( (d = buffer[i] - key[nkey]) < 0)
139              buffer[i] = d + 256;
140          else
141              buffer[i] = d;
142          if ( (nkey + 1) > lenkey)
143              nkey = 0;
144          else
145              nkey++;
146      }
147      return nkey;
148  }  // decodefile
149  
150  
151  int getstring (char *chaine, const int size)
152  {
153      if (!chaine || size < 1) return -1;
154  
155      if (!fgets (chaine, size, stdin) ) return -1;
156      int i;
157      for (i = 0; i < size; i++)
158          if (chaine[i] == '\n')
159          {
160              chaine[i] = '\0';
161              return i;
162          }
163  
164      while ( (i = getchar () ) != '\n' && i != EOF);
165      return size - 1;
166  }  // getstring
167  
168  
169  void closeexit (const char *message, const int result)
170  {
171      if (fe != -1) close (fe);
172      if (fs != -1) close (fs);
173      if (message)
174          printf (message);
175      exit (result);
176  }  // closeexit
177  
178  
179  int main (int argc, char *argv[])
180  {
181      int mode, ext, attr;
182      long bytes, flen, nbuf, lenkey, nkey = 0;
183      char *name, outfile[MAX_PATH] = "\0";
184  
185      if (argc > 1)
186      {
187          if (argc > 2)
188          {
189              strcpy ((char *)key, argv[2]);
190              lenkey = strlen ((char *)key);
191          }
192          else
193          {
194              printf ("Enter the key: ");
195              attr = gettextcolor ();
196              settextcolor (__BACKGROUND);
197              lenkey = (ULONG) getstring ( (char *) key, sizeof (key) );
198              settextcolor (attr & 0x0F);
199          }
200          if (lenkey < 1)
201              closeexit ("Key error.\n", ERROR_KEY);
202  
203  #ifdef ENABLE_CRYPT_KEY
204          nbuf = MAX_KEY;
205          initpi ((char *)buffer, nbuf);
206          codefile (nbuf, 0, lenkey);
207          for (lenkey = 0; lenkey < nbuf; lenkey++)
208              key[lenkey] = buffer[lenkey];
209  #endif  // ENABLE_CRYPT_KEY
210          //printf ("Key length = %ld\n", lenkey);
211  
212          name = argv[1];
213          ext = max (strlen (name) - sizeof (EXT_CODE) + 1, 0);
214          if (ext > 0)
215              if (strcmpi (&name[ext], EXT_CODE) == 0)
216              {
217                  strncpy (outfile, name, ext);
218                  mode = DECODE;
219              }
220  
221          if (outfile[0] == '\0')
222          {
223              strcpy (outfile, name);
224              strcat (outfile, EXT_CODE);
225              mode = CODE;
226          }
227  
228          if ( (fe = open (name   , O_RDONLY |                     O_BINARY, S_IREAD ) ) == -1)
229              closeexit ("Read error in the file.\n", ERROR_FILE);
230          if ( (fs = open (outfile, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IWRITE) ) == -1)
231              closeexit ("Error writing the file.\n", ERROR_FILE);
232  
233          CharToOem (name   , name   );
234          CharToOem (outfile, outfile);
235          printf ("Input  file : \"%s\"\n", name);
236          printf ("Output file : \"%s\"\n", outfile);
237          if (mode == CODE)
238              printf ("Encrypting ...\n");
239          else
240              printf ("Decrypting ...\n");
241  
242          if ( (flen = filelength (fe) ) >= MAX_BUF)
243              nbuf = MAX_BUF;
244          else
245              nbuf = flen;
246  
247          while (flen != 0)
248          {
249              if (read (fe, buffer, nbuf) == -1)
250                  closeexit ("Read error in the file.\n", ERROR_FILE);
251  
252              if (mode == CODE)
253                  nkey =   codefile (nbuf, nkey, lenkey);
254              else
255                  nkey = decodefile (nbuf, nkey, lenkey);
256  
257              bytes = write (fs, buffer, nbuf);
258              if (bytes != nbuf)
259                  closeexit ("Error writing the file.\n", ERROR_FILE);
260  
261              flen -= nbuf;
262              if (flen >= MAX_BUF)
263                  nbuf = MAX_BUF;
264              else
265                  nbuf = flen;
266          }
267          closeexit ("", ERROR_OK);
268      }
269      else
270      {
271          printf (APP_NAME" - Encrypts and decrypts a binary file with the Vigenere cipher.\n");
272          printf ("Usage: "APP_EXE" [filename.ext[.cod]] [\"key\"]\n");
273          return ERROR_ARG;
274      }
275  
276      return ERROR_OK;
277  }  // main
278  
279  
280  /* CodVgn.c */